Portfolio optimization is an important topic in Finance. Modern portfolio theory (MPT) states that investors are risk averse and given a level of risk, they will choose the portfolios that offer the most return. To do that we need to optimize the portfolios.
To perform the optimization we will need
To download the price data of the assets
Assign random weights to the assets
Calculate daily portfolio return, sd, kurtosis, ddve, sign correlation and t df
Use the daily portfolio return, ddve, sign correlation and t df to pick up minimum risk and tangency portfolio and determine the optimal weights
Use the optimal weights of each portfolio to calculate the annualized portflio return, sd and Sharpe ratio to compare all the portfolios
Use GA to compare with the random weights algorithm
So lets begin
First lets load our packages
# list.of.packages <- c('tidyverse','tidyquant', 'plotly','timetk','GA','xtable', 'textreadr','rvest','fGarch',"dplyr", "dygraphs", "quantmod", "TTR", 'zoo', 'tseries', 'fGarch','PEIP','tidyverse','gridExtra', 'gdata', 'xtable',"dygraphs")
# new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
# if(length(new.packages) > 0) {install.packages(new.packages)}
# lapply(list.of.packages, require, character.only=T)
library('tidyverse')
library('tidyquant')
## Warning: package 'xts' was built under R version 4.3.3
## Warning: package 'quantmod' was built under R version 4.3.2
library('plotly')
library('timetk')
library('GA')
## Warning: package 'GA' was built under R version 4.3.2
library('xtable')
#library('textreadr')
library('rvest')
library('fGarch')
library("dplyr")
library("dygraphs")
library("quantmod")
library("TTR")
library('zoo')
library('tseries')
library('fGarch')
library('PEIP')
library('tidyverse')
library('gridExtra')
library('gdata')
library('xtable')
library("dygraphs")
# Load all the required functions needed get the results
## function to generate weight
# get_weights <- function(N){
# return(diff(c(0, sort(runif(N-1, min = 0, max = 1)), 1)))
# }
get_weights <- function(N){
w<- runif(N, min = 0, max = 1)
return(w/sum(w))
}
# skewness correlation
skewrho <- function(X){
skewrho.cor <- cor(X-mean(X), (X-mean(X))^2)
return(skewrho.cor)
}
# sign correlation
rho.cal<-function(X){
rho.hat<-cor(sign(X-mean(X)), X-mean(X))
return(rho.hat)
}
# volatlity correlation
rho.vol<-function(X){
rho.vol<-cor(abs(X-mean(X)), (X-mean(X))^2)
return(rho.vol)
}
Simulation study for sign correlation and volatility correlation
# simulate normal, t(2), t(3), t(4), t(5)
sample <- 8000
sim.n <- rnorm (sample) # sign correlation of a normal distribution is sqrt(2/pi)=0.7979
sim.t25 <- rt (sample, df = 2.5)
sim.t3 <- rt (sample, df = 3)
sim.t35 <- rt (sample, df = 3.5)
sim.t4 <- rt (sample, df = 4)
sim.t5 <- rt (sample, df = 5)
data <- cbind (sim.t25, sim.t3, sim.t35, sim.t4, sim.t5, sim.n)
skewrho<-apply(as.matrix(data), MARGIN=2, FUN=skewrho)
rhosign<-apply(as.matrix(data), MARGIN=2, FUN=rho.cal)
rhovol<-apply(as.matrix(data), MARGIN=2, FUN=rho.vol)
assetsummary<-data.frame(apply(data, 2, mean), apply(data, 2, sd), apply(data, 2, skewness), apply(data, 2, kurtosis), skewrho, rhovol, rhosign)
xtable(assetsummary, digits=4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:26:42 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrr}
## \hline
## & apply.data..2..mean. & apply.data..2..sd. & apply.data..2..skewness. & apply.data..2..kurtosis. & skewrho & rhovol & rhosign \\
## \hline
## sim.t25 & -0.0039 & 2.0243 & -3.5643 & 110.2061 & -0.3365 & 0.6765 & 0.5948 \\
## sim.t3 & 0.0361 & 1.6713 & 0.0165 & 17.0574 & 0.0038 & 0.7844 & 0.6606 \\
## sim.t35 & 0.0065 & 1.5206 & 0.1667 & 9.8920 & 0.0483 & 0.8145 & 0.6935 \\
## sim.t4 & -0.0198 & 1.4764 & -1.2160 & 18.0013 & -0.2719 & 0.7529 & 0.6847 \\
## sim.t5 & -0.0074 & 1.3132 & -0.2010 & 3.7891 & -0.0835 & 0.8706 & 0.7279 \\
## sim.n & 0.0028 & 1.0148 & -0.0237 & -0.0191 & -0.0168 & 0.9370 & 0.7987 \\
## \hline
## \end{tabular}
## \end{table}
Next lets select a few stocks to build our portfolios.
We will choose some stocks.
Lets download the price data.
#Import data
DD_AP_2021_lowest_average_clustering <- read.csv("~/Desktop/PO/AP/DD/2021/DD_AP_2021_lowest_average_clustering.csv")
#remove the date column
asset_prices<-DD_AP_2021_lowest_average_clustering[,-1]
# calculate returns
ret_tidy1 = apply(asset_prices,2, log)
head(ret_tidy1)
## BAC BTC.USD CVX MRNA NVDA PFE XRP.USD
## [1,] 3.309868 10.37261 4.282190 4.716085 2.571176 3.447137 -1.441059
## [2,] 3.317498 10.43389 4.308865 4.692998 2.593143 3.457407 -1.483907
## [3,] 3.378084 10.51391 4.340542 4.755829 2.532381 3.448765 -1.382721
## [4,] 3.399928 10.58079 4.345208 4.745714 2.588601 3.453905 -1.120852
## [5,] 3.389834 10.61638 4.354695 4.725173 2.583548 3.455792 -1.129391
## [6,] 3.406298 10.47916 4.360388 4.764394 2.609184 3.472882 -1.241657
ret_tidy2 = diff(ret_tidy1)
head(ret_tidy2)
## BAC BTC.USD CVX MRNA NVDA PFE
## [1,] 0.007629882 0.06128001 0.026674822 -0.02308738 0.021966844 0.010269978
## [2,] 0.060585677 0.08002183 0.031676631 0.06283118 -0.060762150 -0.008641603
## [3,] 0.021843755 0.06687092 0.004666292 -0.01011468 0.056219881 0.005140180
## [4,] -0.010093625 0.03559289 0.009487136 -0.02054142 -0.005052456 0.001886952
## [5,] 0.016463835 -0.13721491 0.005692940 0.03922073 0.025635094 0.017089982
## [6,] 0.017683496 -0.04731648 0.018817382 0.06031356 -0.010090108 -0.015744267
## XRP.USD
## [1,] -0.042848272
## [2,] 0.101186404
## [3,] 0.261869023
## [4,] -0.008539383
## [5,] -0.112266243
## [6,] 0.011077016
ret_tidy = exp (ret_tidy2) - 1 #simple returns
#remove first row
asset_returns <- ret_tidy[-1,]
#no.of assets in the portfolio
nasset<-ncol(asset_returns)
# testing and training data sets (each data set has 252 observations)
# Divide the data set in to 3:1 (75% training and 25% testing)
# testing period - January - September (189 data points)
# training period - October - December (62 data points)
n.total<-252
n.train<- 189
train = asset_returns[1:n.train,]
test = asset_returns[-(1:(n.train)),]
##summary statistics
rhosign<-apply(as.matrix(train), MARGIN=2, FUN=rho.cal)
rhovol<-apply(as.matrix(train), MARGIN=2, FUN=rho.vol)
assetsummary<-data.frame(apply(train, 2, mean), apply(train, 2, sd), rhovol, rhosign, apply(train, 2, skewness),
apply(train, 2, kurtosis))
xtable(assetsummary, digits=4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:26:42 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrr}
## \hline
## & apply.train..2..mean. & apply.train..2..sd. & rhovol & rhosign & apply.train..2..skewness. & apply.train..2..kurtosis. \\
## \hline
## BAC & 0.0022 & 0.0164 & 0.9187 & 0.8086 & 0.0046 & 0.2690 \\
## BTC.USD & 0.0036 & 0.0524 & 0.9154 & 0.7639 & -0.0173 & 1.0727 \\
## CVX & 0.0014 & 0.0164 & 0.9528 & 0.7889 & -0.1806 & -0.1115 \\
## MRNA & 0.0070 & 0.0472 & 0.9194 & 0.7814 & 0.0317 & 0.7301 \\
## NVDA & 0.0026 & 0.0257 & 0.9333 & 0.7707 & -0.0328 & 0.4990 \\
## PFE & 0.0009 & 0.0123 & 0.9249 & 0.7258 & 0.4701 & 1.7099 \\
## XRP.USD & 0.0129 & 0.0994 & 0.8812 & 0.6629 & 1.3968 & 7.5578 \\
## \hline
## \end{tabular}
## \end{table}
plot(train, legend.loc=1)
## Warning in plot.window(...): "legend.loc" is not a graphical parameter
## Warning in plot.xy(xy, type, ...): "legend.loc" is not a graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "legend.loc" is
## not a graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "legend.loc" is
## not a graphical parameter
## Warning in box(...): "legend.loc" is not a graphical parameter
## Warning in title(...): "legend.loc" is not a graphical parameter
Lets calculate annualized portfolio return, risk, and gamma from the simulated portfolio returns with portfolio weights. (simulated weights)
## portfolio return, sd and gamma
## w is the random weight
## data = train or test
portfolio_info = function(w, data){
port.data <- data%*%as.vector(w)
port.cdf <- ecdf(port.data)
port.return <- mean (port.data)
port.sd <- sd (port.data)
port.signrho <- cor (port.data - port.return, sign(port.data - port.return))
# port.signrho3 <- cor (sign(port.data - port.return), (port.data - port.return)^3)
# port.skewrho <- cor (port.data - port.return, (port.data - port.return)^2)
port.volcor <- cor (abs(port.data - port.return), (port.data - port.return)^2) #volatlity correlation
port.skewness <- skewness (port.data) #mu_3/sigma^3
port.kurtosis <- kurtosis (port.data) #excess kurtosis mu_4/sigma^4 - 3
return(c(port.return, port.sd, port.volcor, port.signrho, port.cdf(port.return), port.skewness, port.kurtosis))
}
# In stat matrix and weight matrix nrow = no.of assets in the portfolio (need to change), ncol is fixed to 7 , for loop i in 1:nrow
stat<-matrix(0, nrow = nasset, ncol = 7)
weight<-matrix(0, nrow = nasset, ncol = nasset)
for (i in 1:nasset){
weight[i, ] <- get_weights(nasset)
stat[i, ] <- portfolio_info (weight[i, ], as.matrix(train))
}
xtable(weight, digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:26:42 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\
## \hline
## 1 & 0.1192 & 0.0555 & 0.2261 & 0.2276 & 0.0683 & 0.1478 & 0.1555 \\
## 2 & 0.1612 & 0.3062 & 0.1045 & 0.0097 & 0.2636 & 0.1207 & 0.0342 \\
## 3 & 0.2037 & 0.1344 & 0.1255 & 0.1763 & 0.1026 & 0.2063 & 0.0511 \\
## 4 & 0.1697 & 0.0245 & 0.1279 & 0.1509 & 0.2122 & 0.1608 & 0.1540 \\
## 5 & 0.0201 & 0.1509 & 0.0701 & 0.1680 & 0.2285 & 0.2422 & 0.1202 \\
## 6 & 0.0154 & 0.1408 & 0.2546 & 0.0493 & 0.1887 & 0.1318 & 0.2193 \\
## 7 & 0.2320 & 0.1814 & 0.1196 & 0.0973 & 0.1751 & 0.0183 & 0.1762 \\
## \hline
## \end{tabular}
## \end{table}
xtable(stat, digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:26:42 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\
## \hline
## 1 & 0.0047 & 0.0214 & 0.9156 & 0.7581 & 0.5185 & 0.2451 & 1.3889 \\
## 2 & 0.0029 & 0.0219 & 0.9176 & 0.7820 & 0.5132 & 0.0117 & 0.7179 \\
## 3 & 0.0035 & 0.0163 & 0.9380 & 0.7912 & 0.4921 & -0.0097 & 0.1520 \\
## 4 & 0.0044 & 0.0205 & 0.9065 & 0.7399 & 0.5185 & 0.4619 & 2.1321 \\
## 5 & 0.0042 & 0.0223 & 0.9369 & 0.7646 & 0.4815 & 0.0120 & 0.6407 \\
## 6 & 0.0047 & 0.0286 & 0.9056 & 0.7233 & 0.4868 & 0.3731 & 2.7084 \\
## 7 & 0.0048 & 0.0268 & 0.9210 & 0.7478 & 0.5079 & 0.1271 & 1.5422 \\
## \hline
## \end{tabular}
## \end{table}
Check for the portfolio sd can be calcualted by both the formula and sd of the simulated portfolio.
We have everything we need to perform our optimization. All we need now is to run this code on 8000 random portfolios. For that we will use a for loop.
Before we do that, we need to create empty vectors and matrix for storing our values.
#change nasset to no of assets in portfolio
num_port <- 10000
nasset <- nasset
# Creating a matrix to store the weights
all_wts1 <- matrix(nrow = num_port,
ncol = nasset)
# Creating an empty vector to store
# 8000 Portfolio returns
port_returns <- vector('numeric', length = num_port)
# Creating an empty vector to store
# 8000 Portfolio variances
port_risk.var1 <- vector('numeric', length = num_port)
port_risk.var2 <- vector('numeric', length = num_port)
port_risk.var3 <- vector('numeric', length = num_port)
port_risk.var4 <- vector('numeric', length = num_port)
port_risk.mad <- vector('numeric', length = num_port)
Sharpe_ratio.sd1 <- vector('numeric', length = num_port)
Sharpe_ratio.sd2 <- vector('numeric', length = num_port)
Sharpe_ratio.sd3 <- vector('numeric', length = num_port)
Sharpe_ratio.sd4 <- vector('numeric', length = num_port)
Sharpe_ratio.mad <- vector('numeric', length = num_port)
Next lets run the for loop 10000 times.
port.info <- matrix(0, nrow = 10000, ncol = 7)
ptm <- proc.time()
for (i in seq_along(port_returns)) {
wts <- get_weights(nasset)
# Storing weight in the matrix
all_wts1[i,] <- wts
# Portfolio returns
port.info [i, ]<- portfolio_info (wts, as.matrix(train))
# Storing Portfolio Returns values
port_returns[i] <- port.info[i, 1]
# Creating and storing portfolio risk
port_risk.var1 [i] <- port.info[i, 2]
port_risk.var2 [i] <- sqrt(1 - port.info[i, 3]^2)*port.info[i, 2]
port_risk.var3 [i] <- sqrt(1 - port.info[i, 4]^2)*port.info[i, 2]
port_risk.var4 [i] <- sqrt(1 - port.info[i, 3]^2)*sqrt(1 - port.info[i, 4]^2)*port.info[i, 2]
port_risk.mad [i] <- 2*port.info[i, 2]*port.info[i, 4]*sqrt(port.info[i, 5]*(1-port.info[i, 5]))
# Creating and storing Portfolio Sharpe Ratios
# Assuming 0% Risk free rate
Sharpe_ratio.sd1 [i] <- port_returns[i]/port_risk.var1 [i]
Sharpe_ratio.sd2 [i] <- port_returns[i]/port_risk.var2 [i]
Sharpe_ratio.sd3 [i] <- port_returns[i]/port_risk.var3 [i]
Sharpe_ratio.sd4 [i] <- port_returns[i]/port_risk.var4 [i]
Sharpe_ratio.mad [i] <- port_returns[i]/port_risk.mad [i]
}
proc.time()-ptm
## user system elapsed
## 11.308 0.144 12.809
port.info.data <- as.data.frame(port.info)
ggplot(port.info.data, aes(x=V6, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Skewness") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V7, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Kurtosis") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V6)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Skewness")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V7)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Kurtosis")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Volatility")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V2, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Volatlity")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Volatility")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V6)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Skewness")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V7)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Kurtosis")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
We now create a data table to store all the values together (using sd).
# Storing the values in the table (5 columns and 8000 rows)
portfolio_values1 <- tibble(Return = port_returns,
Risk1 = port_risk.var1,
Risk2 = port_risk.var2,
Risk3 = port_risk.var3,
Risk4 = port_risk.var4,
Risk5 = port_risk.mad,
SharpeRatio1 = Sharpe_ratio.sd1,
SharpeRatio2 = Sharpe_ratio.sd2,
SharpeRatio3 = Sharpe_ratio.sd3,
SharpeRatio4 = Sharpe_ratio.sd4,
SharpeRatio5 = Sharpe_ratio.mad,
)
# Converting matrix to a tibble and changing column names
all_wts1 <- tk_tbl(all_wts1)
## Warning in tk_tbl.data.frame(as.data.frame(data), preserve_index, rename_index,
## : Warning: No index to preserve. Object otherwise converted to tibble
## successfully.
colnames(all_wts1) <- colnames(asset_returns)
# Combing all the values together
portfolio_values1 <- tk_tbl(cbind(all_wts1, portfolio_values1))
## Warning in tk_tbl.data.frame(cbind(all_wts1, portfolio_values1)): Warning: No
## index to preserve. Object otherwise converted to tibble successfully.
We have the weights in each asset with the risk and returns along with the Sharpe ratio of each portfolio. We use daily data to determine the portfolios.
Next lets look at the portfolios that matter the most.
min_var1 <- portfolio_values1[which.min(portfolio_values1$Risk1),]
min_var2 <- portfolio_values1[which.min(portfolio_values1$Risk2),]
min_var3 <- portfolio_values1[which.min(portfolio_values1$Risk3),]
min_var4 <- portfolio_values1[which.min(portfolio_values1$Risk4),]
min_mad <- portfolio_values1[which.min(portfolio_values1$Risk5),]
max_sr1 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio1),]
max_sr2 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio2),]
max_sr3 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio3),]
max_sr4 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio4),]
max_sr5 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio5),]
rbind(min_var1, min_var2, min_var3, min_var4, min_mad, max_sr1, max_sr2, max_sr3, max_sr4, max_sr5)
## # A tibble: 10 × 18
## BAC BTC.USD CVX MRNA NVDA PFE XRP.USD Return Risk1 Risk2
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.0895 0.00806 0.237 0.0321 0.157 0.475 0.00102 0.00163 0.00977 0.00340
## 2 0.200 0.0133 0.293 0.0341 0.0973 0.332 0.0295 0.00207 0.0104 0.00337
## 3 0.0895 0.00806 0.237 0.0321 0.157 0.475 0.00102 0.00163 0.00977 0.00340
## 4 0.200 0.0133 0.293 0.0341 0.0973 0.332 0.0295 0.00207 0.0104 0.00337
## 5 0.0895 0.00806 0.237 0.0321 0.157 0.475 0.00102 0.00163 0.00977 0.00340
## 6 0.281 0.00432 0.144 0.204 0.133 0.160 0.0741 0.00371 0.0152 0.00466
## 7 0.209 0.000588 0.218 0.143 0.157 0.228 0.0438 0.00295 0.0124 0.00346
## 8 0.281 0.00432 0.144 0.204 0.133 0.160 0.0741 0.00371 0.0152 0.00466
## 9 0.209 0.000588 0.218 0.143 0.157 0.228 0.0438 0.00295 0.0124 0.00346
## 10 0.520 0.00423 0.00300 0.124 0.0425 0.204 0.102 0.00366 0.0154 0.00595
## # ℹ 8 more variables: Risk3 <dbl>, Risk4 <dbl>, Risk5 <dbl>,
## # SharpeRatio1 <dbl>, SharpeRatio2 <dbl>, SharpeRatio3 <dbl>,
## # SharpeRatio4 <dbl>, SharpeRatio5 <dbl>
xtable(rbind(min_var1, min_var2, min_var3, min_var4, min_mad, max_sr1, max_sr2, max_sr3, max_sr4, max_sr5), digits = 6)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:27:14 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrrrrrrrrrrrrr}
## \hline
## & BAC & BTC.USD & CVX & MRNA & NVDA & PFE & XRP.USD & Return & Risk1 & Risk2 & Risk3 & Risk4 & Risk5 & SharpeRatio1 & SharpeRatio2 & SharpeRatio3 & SharpeRatio4 & SharpeRatio5 \\
## \hline
## 1 & 0.089460 & 0.008064 & 0.237361 & 0.032060 & 0.157041 & 0.474995 & 0.001019 & 0.001632 & 0.009771 & 0.003396 & 0.005764 & 0.002004 & 0.007884 & 0.166991 & 0.480439 & 0.283065 & 0.814387 & 0.206955 \\
## 2 & 0.200102 & 0.013271 & 0.293431 & 0.034135 & 0.097301 & 0.332287 & 0.029474 & 0.002071 & 0.010395 & 0.003373 & 0.005989 & 0.001944 & 0.008493 & 0.199231 & 0.613970 & 0.345785 & 1.065605 & 0.243844 \\
## 3 & 0.089460 & 0.008064 & 0.237361 & 0.032060 & 0.157041 & 0.474995 & 0.001019 & 0.001632 & 0.009771 & 0.003396 & 0.005764 & 0.002004 & 0.007884 & 0.166991 & 0.480439 & 0.283065 & 0.814387 & 0.206955 \\
## 4 & 0.200102 & 0.013271 & 0.293431 & 0.034135 & 0.097301 & 0.332287 & 0.029474 & 0.002071 & 0.010395 & 0.003373 & 0.005989 & 0.001944 & 0.008493 & 0.199231 & 0.613970 & 0.345785 & 1.065605 & 0.243844 \\
## 5 & 0.089460 & 0.008064 & 0.237361 & 0.032060 & 0.157041 & 0.474995 & 0.001019 & 0.001632 & 0.009771 & 0.003396 & 0.005764 & 0.002004 & 0.007884 & 0.166991 & 0.480439 & 0.283065 & 0.814387 & 0.206955 \\
## 6 & 0.280930 & 0.004319 & 0.143586 & 0.204481 & 0.132510 & 0.160048 & 0.074126 & 0.003714 & 0.015190 & 0.004662 & 0.009091 & 0.002790 & 0.012168 & 0.244514 & 0.796629 & 0.408547 & 1.331050 & 0.305252 \\
## 7 & 0.209461 & 0.000588 & 0.218397 & 0.143141 & 0.156713 & 0.227861 & 0.043838 & 0.002949 & 0.012440 & 0.003462 & 0.007229 & 0.002012 & 0.010124 & 0.237066 & 0.851909 & 0.407970 & 1.466060 & 0.291297 \\
## 8 & 0.280930 & 0.004319 & 0.143586 & 0.204481 & 0.132510 & 0.160048 & 0.074126 & 0.003714 & 0.015190 & 0.004662 & 0.009091 & 0.002790 & 0.012168 & 0.244514 & 0.796629 & 0.408547 & 1.331050 & 0.305252 \\
## 9 & 0.209461 & 0.000588 & 0.218397 & 0.143141 & 0.156713 & 0.227861 & 0.043838 & 0.002949 & 0.012440 & 0.003462 & 0.007229 & 0.002012 & 0.010124 & 0.237066 & 0.851909 & 0.407970 & 1.466060 & 0.291297 \\
## 10 & 0.520348 & 0.004233 & 0.002997 & 0.123873 & 0.042513 & 0.204016 & 0.102020 & 0.003655 & 0.015391 & 0.005954 & 0.009868 & 0.003818 & 0.011811 & 0.237496 & 0.613886 & 0.370417 & 0.957462 & 0.309483 \\
## \hline
## \end{tabular}
## \end{table}
# change min_var1[1:nassets] and all the indexes after that accordingly
p1 <- cbind(min_var1[1:nasset], 252*min_var1[nasset+1], sqrt(252)*min_var1[nasset+2], sqrt(252)*min_var1[nasset+7])
p2 <- cbind(min_var2[1:nasset], 252*min_var2[nasset+1], sqrt(252)*min_var2[nasset+3], sqrt(252)*min_var2[nasset+8])
p3 <- cbind(min_var3[1:nasset], 252*min_var3[nasset+1], sqrt(252)*min_var3[nasset+4], sqrt(252)*min_var3[nasset+9])
p4 <- cbind(min_var4[1:nasset], 252*min_var4[nasset+1], sqrt(252)*min_var4[nasset+5], sqrt(252)*min_var4[nasset+10])
p5 <- cbind(min_mad[1:nasset], 252*min_mad[nasset+1], sqrt(252)*min_mad[nasset+6], sqrt(252)*min_mad[nasset+11])
xtable(t(rbind(as.numeric(p1), as.numeric(p2), as.numeric(p3), as.numeric(p4), as.numeric(p5))), digits = 5)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:27:14 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.08946 & 0.20010 & 0.08946 & 0.20010 & 0.08946 \\
## 2 & 0.00806 & 0.01327 & 0.00806 & 0.01327 & 0.00806 \\
## 3 & 0.23736 & 0.29343 & 0.23736 & 0.29343 & 0.23736 \\
## 4 & 0.03206 & 0.03413 & 0.03206 & 0.03413 & 0.03206 \\
## 5 & 0.15704 & 0.09730 & 0.15704 & 0.09730 & 0.15704 \\
## 6 & 0.47499 & 0.33229 & 0.47499 & 0.33229 & 0.47499 \\
## 7 & 0.00102 & 0.02947 & 0.00102 & 0.02947 & 0.00102 \\
## 8 & 0.41117 & 0.52190 & 0.41117 & 0.52190 & 0.41117 \\
## 9 & 0.15511 & 0.05355 & 0.09150 & 0.03085 & 0.12515 \\
## 10 & 2.65090 & 9.74647 & 4.49351 & 16.91595 & 3.28532 \\
## \hline
## \end{tabular}
## \end{table}
# change max_sr[1:nassets] and all the indexes after that accordingly
p1 <- cbind(max_sr1[1:nasset], 252*max_sr1[nasset+1], sqrt(252)*max_sr1[nasset+2], sqrt(252)*max_sr1[nasset+7])
p2 <- cbind(max_sr2[1:nasset], 252*max_sr2[nasset+1], sqrt(252)*max_sr2[nasset+3], sqrt(252)*max_sr2[nasset+8])
p3 <- cbind(max_sr3[1:nasset], 252*max_sr3[nasset+1], sqrt(252)*max_sr3[nasset+4], sqrt(252)*max_sr3[nasset+9])
p4 <- cbind(max_sr4[1:nasset], 252*max_sr4[nasset+1], sqrt(252)*max_sr4[nasset+5], sqrt(252)*max_sr4[nasset+10])
p5 <- cbind(max_sr5[1:nasset], 252*max_sr5[nasset+1], sqrt(252)*max_sr5[nasset+6], sqrt(252)*max_sr5[nasset+11])
xtable(t(rbind(as.numeric(p1), as.numeric(p2), as.numeric(p3), as.numeric(p4), as.numeric(p5))), digits = 5)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:27:14 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.28093 & 0.20946 & 0.28093 & 0.20946 & 0.52035 \\
## 2 & 0.00432 & 0.00059 & 0.00432 & 0.00059 & 0.00423 \\
## 3 & 0.14359 & 0.21840 & 0.14359 & 0.21840 & 0.00300 \\
## 4 & 0.20448 & 0.14314 & 0.20448 & 0.14314 & 0.12387 \\
## 5 & 0.13251 & 0.15671 & 0.13251 & 0.15671 & 0.04251 \\
## 6 & 0.16005 & 0.22786 & 0.16005 & 0.22786 & 0.20402 \\
## 7 & 0.07413 & 0.04384 & 0.07413 & 0.04384 & 0.10202 \\
## 8 & 0.93598 & 0.74317 & 0.93598 & 0.74317 & 0.92115 \\
## 9 & 0.24114 & 0.05495 & 0.14432 & 0.03193 & 0.18750 \\
## 10 & 3.88154 & 13.52363 & 6.48548 & 23.27299 & 4.91289 \\
## \hline
## \end{tabular}
## \end{table}
nasset <- ncol(asset_returns)
w1 <- min_var1[, 1:nasset] %>% gather () %>% arrange(desc(value))
w2 <- min_var2[, 1:nasset] %>% gather () %>% arrange(desc(value))
w3 <- min_var3[, 1:nasset] %>% gather () %>% arrange(desc(value))
w4 <- min_var4[, 1:nasset] %>% gather () %>% arrange(desc(value))
w5 <- min_mad[, 1:nasset] %>% gather () %>% arrange(desc(value))
w6 <- max_sr1[, 1:nasset] %>% gather () %>% arrange(desc(value))
w7 <- max_sr2[, 1:nasset] %>% gather () %>% arrange(desc(value))
w8 <- max_sr3[, 1:nasset] %>% gather () %>% arrange(desc(value))
w9 <- max_sr4[, 1:nasset] %>% gather () %>% arrange(desc(value))
w10 <- max_sr5[, 1:nasset] %>% gather () %>% arrange(desc(value))
xtable(cbind(head (w1, 10), head (w2, 10), head (w3, 10), head (w4, 10), head (w5, 10), head (w6, 10), head (w7, 10), head (w8, 10), head (w9, 10), head (w10, 10)), digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:27:14 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rlrlrlrlrlrlrlrlrlrlr}
## \hline
## & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value \\
## \hline
## 1 & PFE & 0.4750 & PFE & 0.3323 & PFE & 0.4750 & PFE & 0.3323 & PFE & 0.4750 & BAC & 0.2809 & PFE & 0.2279 & BAC & 0.2809 & PFE & 0.2279 & BAC & 0.5203 \\
## 2 & CVX & 0.2374 & CVX & 0.2934 & CVX & 0.2374 & CVX & 0.2934 & CVX & 0.2374 & MRNA & 0.2045 & CVX & 0.2184 & MRNA & 0.2045 & CVX & 0.2184 & PFE & 0.2040 \\
## 3 & NVDA & 0.1570 & BAC & 0.2001 & NVDA & 0.1570 & BAC & 0.2001 & NVDA & 0.1570 & PFE & 0.1600 & BAC & 0.2095 & PFE & 0.1600 & BAC & 0.2095 & MRNA & 0.1239 \\
## 4 & BAC & 0.0895 & NVDA & 0.0973 & BAC & 0.0895 & NVDA & 0.0973 & BAC & 0.0895 & CVX & 0.1436 & NVDA & 0.1567 & CVX & 0.1436 & NVDA & 0.1567 & XRP.USD & 0.1020 \\
## 5 & MRNA & 0.0321 & MRNA & 0.0341 & MRNA & 0.0321 & MRNA & 0.0341 & MRNA & 0.0321 & NVDA & 0.1325 & MRNA & 0.1431 & NVDA & 0.1325 & MRNA & 0.1431 & NVDA & 0.0425 \\
## 6 & BTC.USD & 0.0081 & XRP.USD & 0.0295 & BTC.USD & 0.0081 & XRP.USD & 0.0295 & BTC.USD & 0.0081 & XRP.USD & 0.0741 & XRP.USD & 0.0438 & XRP.USD & 0.0741 & XRP.USD & 0.0438 & BTC.USD & 0.0042 \\
## 7 & XRP.USD & 0.0010 & BTC.USD & 0.0133 & XRP.USD & 0.0010 & BTC.USD & 0.0133 & XRP.USD & 0.0010 & BTC.USD & 0.0043 & BTC.USD & 0.0006 & BTC.USD & 0.0043 & BTC.USD & 0.0006 & CVX & 0.0030 \\
## \hline
## \end{tabular}
## \end{table}
Lets plot the weights of each portfolio. First with the minimum variance portfolio.
p1 <- min_var4 %>%
gather(colnames(asset_returns)[1]:colnames(asset_returns)[nasset], key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset,Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Assets', y = 'Weights', title = "Minimum Risk Portfolio Weights") +
scale_y_continuous(labels = scales::percent)
ggplotly(p1)
p2 <- max_sr4 %>%
gather(colnames(asset_returns)[1]:colnames(asset_returns)[nasset], key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset, Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Assets', y = 'Weights', title = "Tangency Portfolio Weights") +
scale_y_continuous(labels = scales::percent)
ggplotly(p2)
#convert daily return, risk, SR to annualized ones
portfolio_values1_annual <- portfolio_values1 %>% mutate(Return = Return * 252) %>% mutate(Risk1 = Risk1 * sqrt(252), Risk2 = Risk2 * sqrt(252), Risk3 = Risk3 * sqrt(252), Risk4 = Risk4 * sqrt(252), Risk5 = Risk5 * sqrt(252)) %>% mutate(SharpeRatio1 = SharpeRatio1 * sqrt(252), SharpeRatio2 = SharpeRatio2 * sqrt(252), SharpeRatio3 = SharpeRatio3 * sqrt(252), SharpeRatio4 = SharpeRatio4 * sqrt(252), SharpeRatio5 = SharpeRatio5 * sqrt(252))
min_var1.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk1),]
min_var2.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk2),]
min_var3.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk3),]
min_var4.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk4),]
min_mad.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk5),]
max_sr1.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio1),]
max_sr2.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio2),]
max_sr3.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio3),]
max_sr4.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio4),]
max_sr5.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio5),]
rbind(min_var1.a, min_var2.a, min_var3.a, min_var4.a, min_mad.a, max_sr1.a, max_sr2.a, max_sr3.a, max_sr4.a, max_sr5.a)
## # A tibble: 10 × 18
## BAC BTC.USD CVX MRNA NVDA PFE XRP.USD Return Risk1 Risk2 Risk3
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.0895 8.06e-3 0.237 0.0321 0.157 0.475 0.00102 0.411 0.155 0.0539 0.0915
## 2 0.200 1.33e-2 0.293 0.0341 0.0973 0.332 0.0295 0.522 0.165 0.0535 0.0951
## 3 0.0895 8.06e-3 0.237 0.0321 0.157 0.475 0.00102 0.411 0.155 0.0539 0.0915
## 4 0.200 1.33e-2 0.293 0.0341 0.0973 0.332 0.0295 0.522 0.165 0.0535 0.0951
## 5 0.0895 8.06e-3 0.237 0.0321 0.157 0.475 0.00102 0.411 0.155 0.0539 0.0915
## 6 0.281 4.32e-3 0.144 0.204 0.133 0.160 0.0741 0.936 0.241 0.0740 0.144
## 7 0.209 5.88e-4 0.218 0.143 0.157 0.228 0.0438 0.743 0.197 0.0550 0.115
## 8 0.281 4.32e-3 0.144 0.204 0.133 0.160 0.0741 0.936 0.241 0.0740 0.144
## 9 0.209 5.88e-4 0.218 0.143 0.157 0.228 0.0438 0.743 0.197 0.0550 0.115
## 10 0.520 4.23e-3 0.00300 0.124 0.0425 0.204 0.102 0.921 0.244 0.0945 0.157
## # ℹ 7 more variables: Risk4 <dbl>, Risk5 <dbl>, SharpeRatio1 <dbl>,
## # SharpeRatio2 <dbl>, SharpeRatio3 <dbl>, SharpeRatio4 <dbl>,
## # SharpeRatio5 <dbl>
p1 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk1, y = Return, color = SharpeRatio1)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (SD)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk1,
y = Return), data = min_var1.a, color = 'orange') +
geom_point(aes(x = Risk1,
y = Return), data = max_sr1.a, color = 'orange4', shape = 18)
ggplotly(p1)
p2 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk2, y = Return, color = SharpeRatio2)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VEV)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk2,
y = Return), data = min_var2.a, color = 'green') +
geom_point(aes(x = Risk2,
y = Return), data = max_sr2.a, color = 'green4', shape = 18)
ggplotly(p2)
p3 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk3, y = Return, color = SharpeRatio3)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VES)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk3,
y = Return), data = min_var3.a, color = 'red') +
geom_point(aes(x = Risk3,
y = Return), data = max_sr3.a, color = 'red4', shape = 18)
ggplotly(p3)
p4 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk4, y = Return, color = SharpeRatio4)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VESV)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk4,
y = Return), data = min_var4.a, color = 'purple') +
geom_point(aes(x = Risk4,
y = Return), data = max_sr4.a, color = 'purple4', shape = 18)
ggplotly(p4)
p5 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk5, y = Return, color = SharpeRatio5)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (MAD)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk5,
y = Return), data = min_mad.a, color = 'blue') +
geom_point(aes(x = Risk5,
y = Return), data = max_sr5.a, color = 'blue4', shape = 18)
ggplotly(p5)
MVP1 <- as.matrix(test)%*%as.vector(as.numeric(min_var1[1:nasset]))
MVP2 <- as.matrix(test)%*%as.vector(as.numeric(min_var2[1:nasset]))
MVP3 <- as.matrix(test)%*%as.vector(as.numeric(min_var3[1:nasset]))
MVP4 <- as.matrix(test)%*%as.vector(as.numeric(min_var4[1:nasset]))
MVP5 <- as.matrix(test)%*%as.vector(as.numeric(min_mad[1:nasset]))
TP1<-as.matrix(test)%*%as.vector(as.numeric(max_sr1[1:nasset]))
TP2<-as.matrix(test)%*%as.vector(as.numeric(max_sr2[1:nasset]))
TP3<-as.matrix(test)%*%as.vector(as.numeric(max_sr3[1:nasset]))
TP4<-as.matrix(test)%*%as.vector(as.numeric(max_sr4[1:nasset]))
TP5<-as.matrix(test)%*%as.vector(as.numeric(max_sr5[1:nasset]))
EWQ<-as.matrix(test)%*%as.vector(rep(1/nasset, nasset))
assets <- c("MVP1", "MVP2", "MVP3", "MVP4", "MVP5", "TP1", "TP2", "TP3", "TP4", "TP5", "EWQ")
#Portfolios <- merge(test[, 1], cumsum(MVP1), cumsum(MVP2), cumsum(MVP3), cumsum(MVP4), cumsum(MVP5), cumsum(TP1), cumsum(TP2), cumsum(TP3), cumsum(TP4), cumsum(TP5), cumsum(EWQ))[, -c(1)]
Portfolios <- cbind.data.frame(cumsum(MVP1), cumsum(MVP2), cumsum(MVP3), cumsum(MVP4), cumsum(MVP5), cumsum(TP1), cumsum(TP2), cumsum(TP3), cumsum(TP4), cumsum(TP5), cumsum(EWQ))
colnames(Portfolios) <- assets
# Define start and end dates
start_date <- as.Date("2021-01-01")
end_date <- as.Date("2021-12-31")
# Create a sequence of dates
date_sequence <- seq(start_date, end_date, by = "day")
#date_sequence
# Number of last values to select
nTemp <- nrow(Portfolios)
# Select the last 'n' values from the vector
TestDates <- date_sequence[(length(date_sequence) - nTemp + 1):length(date_sequence)]
#TestDates
row.names(Portfolios) <- TestDates
dygraph(Portfolios, main = 'Cummulative Returns for Test Period')%>%
dySeries('MVP1', label = 'MVP', col = "orange") %>%
dySeries('MVP2', label = 'MRP2', col = "green") %>%
dySeries('MVP3', label = 'MRP3', col = "red") %>%
dySeries('MVP4', label = 'MRP4', col = "purple") %>%
dySeries('MVP5', label = 'MRP5', col = "blue") %>%
dySeries('TP1', label = 'TP', col = "orange", drawPoints = TRUE) %>%
dySeries('TP2', label = 'MRRP2', col = "green", drawPoints = TRUE) %>%
dySeries('TP3', label = 'MRRP3', col = "red", drawPoints = TRUE) %>%
dySeries('TP4', label = 'MRRP4', col = "purple", drawPoints = TRUE) %>%
dySeries('TP5', label = 'MRRP5', col = "blue", drawPoints = TRUE) %>%
dySeries('EWQ', label = 'EWQ', col = "black") %>%
dyRangeSelector(height = 30)%>%
dyLegend(width = 500)
CumReturnVolCorr_low_avg_risk <- cumsum(TP2)
CumReturnVolCorr_low_avg_risk
## [1] -0.014600733 -0.003987908 -0.003674135 -0.008075017 -0.009075692
## [6] -0.004164200 0.019461532 0.024015210 0.027673732 0.037399040
## [11] 0.047307049 0.048657117 0.050323648 0.065460700 0.079510116
## [16] 0.060346998 0.075710750 0.085084000 0.083655204 0.102014285
## [21] 0.102277475 0.088762793 0.088831902 0.104758623 0.093343988
## [26] 0.086518133 0.096989651 0.094874880 0.099937047 0.098107344
## [31] 0.100613065 0.116488057 0.120397735 0.133305458 0.139950903
## [36] 0.143340956 0.163401552 0.185371291 0.173003228 0.149314863
## [41] 0.152863051 0.145208512 0.111083358 0.139174604 0.136190146
## [46] 0.127831604 0.118869632 0.117094890 0.126229180 0.154103327
## [51] 0.158256350 0.143622449 0.141200935 0.148770880 0.145881663
## [56] 0.146153303 0.155713458 0.141181464 0.138322747 0.141356282
#Import data
DD_AP_2021_lowest_risk <- read.csv("~/Desktop/PO/AP/DD/2021/DD_AP_2021_lowest_risk.csv")
#remove the date column
asset_prices<-DD_AP_2021_lowest_risk[,-1]
# calculate returns
ret_tidy1 = apply(asset_prices,2, log)
head(ret_tidy1)
## AAPL BAC CVX NVDA PEP SLB XRP.USD
## [1,] 4.841691 3.309868 4.282190 2.571176 4.865140 3.018983 -1.441059
## [2,] 4.853979 3.317498 4.308865 2.593143 4.868116 3.071346 -1.483907
## [3,] 4.819738 3.378084 4.340542 2.532381 4.855809 3.125209 -1.382721
## [4,] 4.853292 3.399928 4.345208 2.588601 4.852585 3.144280 -1.120852
## [5,] 4.861886 3.389834 4.354695 2.583548 4.864516 3.142671 -1.129391
## [6,] 4.838363 3.406298 4.360388 2.609184 4.849914 3.148692 -1.241657
ret_tidy2 = diff(ret_tidy1)
head(ret_tidy2)
## AAPL BAC CVX NVDA PEP
## [1,] 0.012288257 0.007629882 0.026674822 0.021966844 0.002976045
## [2,] -0.034241207 0.060585677 0.031676631 -0.060762150 -0.012307619
## [3,] 0.033553997 0.021843755 0.004666292 0.056219881 -0.003223697
## [4,] 0.008593906 -0.010093625 0.009487136 -0.005052456 0.011931143
## [5,] -0.023523290 0.016463835 0.005692940 0.025635094 -0.014602024
## [6,] -0.001396306 0.017683496 0.018817382 -0.010090108 -0.004655676
## SLB XRP.USD
## [1,] 0.052363324 -0.042848272
## [2,] 0.053862326 0.101186404
## [3,] 0.019071487 0.261869023
## [4,] -0.001609016 -0.008539383
## [5,] 0.006020548 -0.112266243
## [6,] 0.044990906 0.011077016
ret_tidy = exp (ret_tidy2) - 1 #simple returns
#remove first row
asset_returns <- ret_tidy[-1,]
#no.of assets in the portfolio
nasset<-ncol(asset_returns)
# testing and training data sets (each data set has 252 observations)
# Divide the data set in to 3:1 (75% training and 25% testing)
# testing period - January - September (189 data points)
# training period - October - December (62 data points)
n.total<-252
n.train<- 189
train = asset_returns[1:n.train,]
test = asset_returns[-(1:(n.train)),]
##summary statistics
rhosign<-apply(as.matrix(train), MARGIN=2, FUN=rho.cal)
rhovol<-apply(as.matrix(train), MARGIN=2, FUN=rho.vol)
assetsummary<-data.frame(apply(train, 2, mean), apply(train, 2, sd), rhovol, rhosign, apply(train, 2, skewness),
apply(train, 2, kurtosis))
xtable(assetsummary, digits=4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:27:19 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrr}
## \hline
## & apply.train..2..mean. & apply.train..2..sd. & rhovol & rhosign & apply.train..2..skewness. & apply.train..2..kurtosis. \\
## \hline
## AAPL & 0.0005 & 0.0160 & 0.9370 & 0.7717 & -0.0186 & 0.3885 \\
## BAC & 0.0022 & 0.0164 & 0.9187 & 0.8086 & 0.0046 & 0.2690 \\
## CVX & 0.0014 & 0.0164 & 0.9528 & 0.7889 & -0.1806 & -0.1115 \\
## NVDA & 0.0026 & 0.0257 & 0.9333 & 0.7707 & -0.0328 & 0.4990 \\
## PEP & 0.0004 & 0.0090 & 0.9213 & 0.7528 & 0.0377 & 0.7929 \\
## SLB & 0.0019 & 0.0269 & 0.9470 & 0.8051 & 0.4103 & -0.1663 \\
## XRP.USD & 0.0129 & 0.0994 & 0.8812 & 0.6629 & 1.3968 & 7.5578 \\
## \hline
## \end{tabular}
## \end{table}
plot(train, legend.loc=1)
## Warning in plot.window(...): "legend.loc" is not a graphical parameter
## Warning in plot.xy(xy, type, ...): "legend.loc" is not a graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "legend.loc" is
## not a graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "legend.loc" is
## not a graphical parameter
## Warning in box(...): "legend.loc" is not a graphical parameter
## Warning in title(...): "legend.loc" is not a graphical parameter
Lets calculate annualized portfolio return, risk, and gamma from the simulated portfolio returns with portfolio weights. (simulated weights)
## portfolio return, sd and gamma
## w is the random weight
## data = train or test
portfolio_info = function(w, data){
port.data <- data%*%as.vector(w)
port.cdf <- ecdf(port.data)
port.return <- mean (port.data)
port.sd <- sd (port.data)
port.signrho <- cor (port.data - port.return, sign(port.data - port.return))
# port.signrho3 <- cor (sign(port.data - port.return), (port.data - port.return)^3)
# port.skewrho <- cor (port.data - port.return, (port.data - port.return)^2)
port.volcor <- cor (abs(port.data - port.return), (port.data - port.return)^2) #volatlity correlation
port.skewness <- skewness (port.data) #mu_3/sigma^3
port.kurtosis <- kurtosis (port.data) #excess kurtosis mu_4/sigma^4 - 3
return(c(port.return, port.sd, port.volcor, port.signrho, port.cdf(port.return), port.skewness, port.kurtosis))
}
# In stat matrix and weight matrix nrow = no.of assets in the portfolio (need to change), ncol is fixed to 7 , for loop i in 1:nrow
stat<-matrix(0, nrow = nasset, ncol = 7)
weight<-matrix(0, nrow = nasset, ncol = nasset)
for (i in 1:nasset){
weight[i, ] <- get_weights(nasset)
stat[i, ] <- portfolio_info (weight[i, ], as.matrix(train))
}
xtable(weight, digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:27:19 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\
## \hline
## 1 & 0.0688 & 0.1023 & 0.2170 & 0.0292 & 0.1982 & 0.0800 & 0.3045 \\
## 2 & 0.0176 & 0.1855 & 0.1935 & 0.1355 & 0.1516 & 0.1908 & 0.1254 \\
## 3 & 0.0974 & 0.2155 & 0.0493 & 0.1332 & 0.2839 & 0.1550 & 0.0657 \\
## 4 & 0.1915 & 0.0401 & 0.0310 & 0.1800 & 0.0526 & 0.2776 & 0.2273 \\
## 5 & 0.0333 & 0.2157 & 0.1086 & 0.0144 & 0.1909 & 0.2009 & 0.2361 \\
## 6 & 0.0507 & 0.0567 & 0.0403 & 0.2013 & 0.2695 & 0.1174 & 0.2642 \\
## 7 & 0.1749 & 0.2285 & 0.0104 & 0.1991 & 0.0745 & 0.0598 & 0.2527 \\
## \hline
## \end{tabular}
## \end{table}
xtable(stat, digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:27:19 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\
## \hline
## 1 & 0.0048 & 0.0320 & 0.8823 & 0.6848 & 0.5132 & 1.1836 & 6.0115 \\
## 2 & 0.0031 & 0.0179 & 0.9117 & 0.7703 & 0.5344 & 0.4256 & 1.3643 \\
## 3 & 0.0022 & 0.0126 & 0.9297 & 0.7781 & 0.4921 & 0.1333 & 0.6359 \\
## 4 & 0.0042 & 0.0271 & 0.8940 & 0.7266 & 0.5185 & 0.8898 & 3.6876 \\
## 5 & 0.0042 & 0.0265 & 0.8863 & 0.7245 & 0.5291 & 0.9475 & 4.2399 \\
## 6 & 0.0045 & 0.0292 & 0.8856 & 0.6880 & 0.5132 & 1.1654 & 5.6298 \\
## 7 & 0.0045 & 0.0286 & 0.8892 & 0.6963 & 0.5132 & 1.1675 & 5.4866 \\
## \hline
## \end{tabular}
## \end{table}
Check for the portfolio sd can be calcualted by both the formula and sd of the simulated portfolio.
We have everything we need to perform our optimization. All we need now is to run this code on 8000 random portfolios. For that we will use a for loop.
Before we do that, we need to create empty vectors and matrix for storing our values.
#change nasset to no of assets in portfolio
num_port <- 10000
nasset <- nasset
# Creating a matrix to store the weights
all_wts1 <- matrix(nrow = num_port,
ncol = nasset)
# Creating an empty vector to store
# 8000 Portfolio returns
port_returns <- vector('numeric', length = num_port)
# Creating an empty vector to store
# 8000 Portfolio variances
port_risk.var1 <- vector('numeric', length = num_port)
port_risk.var2 <- vector('numeric', length = num_port)
port_risk.var3 <- vector('numeric', length = num_port)
port_risk.var4 <- vector('numeric', length = num_port)
port_risk.mad <- vector('numeric', length = num_port)
Sharpe_ratio.sd1 <- vector('numeric', length = num_port)
Sharpe_ratio.sd2 <- vector('numeric', length = num_port)
Sharpe_ratio.sd3 <- vector('numeric', length = num_port)
Sharpe_ratio.sd4 <- vector('numeric', length = num_port)
Sharpe_ratio.mad <- vector('numeric', length = num_port)
Next lets run the for loop 10000 times.
port.info <- matrix(0, nrow = 10000, ncol = 7)
ptm <- proc.time()
for (i in seq_along(port_returns)) {
wts <- get_weights(nasset)
# Storing weight in the matrix
all_wts1[i,] <- wts
# Portfolio returns
port.info [i, ]<- portfolio_info (wts, as.matrix(train))
# Storing Portfolio Returns values
port_returns[i] <- port.info[i, 1]
# Creating and storing portfolio risk
port_risk.var1 [i] <- port.info[i, 2]
port_risk.var2 [i] <- sqrt(1 - port.info[i, 3]^2)*port.info[i, 2]
port_risk.var3 [i] <- sqrt(1 - port.info[i, 4]^2)*port.info[i, 2]
port_risk.var4 [i] <- sqrt(1 - port.info[i, 3]^2)*sqrt(1 - port.info[i, 4]^2)*port.info[i, 2]
port_risk.mad [i] <- 2*port.info[i, 2]*port.info[i, 4]*sqrt(port.info[i, 5]*(1-port.info[i, 5]))
# Creating and storing Portfolio Sharpe Ratios
# Assuming 0% Risk free rate
Sharpe_ratio.sd1 [i] <- port_returns[i]/port_risk.var1 [i]
Sharpe_ratio.sd2 [i] <- port_returns[i]/port_risk.var2 [i]
Sharpe_ratio.sd3 [i] <- port_returns[i]/port_risk.var3 [i]
Sharpe_ratio.sd4 [i] <- port_returns[i]/port_risk.var4 [i]
Sharpe_ratio.mad [i] <- port_returns[i]/port_risk.mad [i]
}
proc.time()-ptm
## user system elapsed
## 10.008 0.133 10.797
port.info.data <- as.data.frame(port.info)
ggplot(port.info.data, aes(x=V6, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Skewness") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V7, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Kurtosis") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V6)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Skewness")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V7)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Kurtosis")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Volatility")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V2, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Volatlity")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Volatility")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V6)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Skewness")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V7)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Kurtosis")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
We now create a data table to store all the values together (using sd).
# Storing the values in the table (5 columns and 8000 rows)
portfolio_values1 <- tibble(Return = port_returns,
Risk1 = port_risk.var1,
Risk2 = port_risk.var2,
Risk3 = port_risk.var3,
Risk4 = port_risk.var4,
Risk5 = port_risk.mad,
SharpeRatio1 = Sharpe_ratio.sd1,
SharpeRatio2 = Sharpe_ratio.sd2,
SharpeRatio3 = Sharpe_ratio.sd3,
SharpeRatio4 = Sharpe_ratio.sd4,
SharpeRatio5 = Sharpe_ratio.mad,
)
# Converting matrix to a tibble and changing column names
all_wts1 <- tk_tbl(all_wts1)
## Warning in tk_tbl.data.frame(as.data.frame(data), preserve_index, rename_index,
## : Warning: No index to preserve. Object otherwise converted to tibble
## successfully.
colnames(all_wts1) <- colnames(asset_returns)
# Combing all the values together
portfolio_values1 <- tk_tbl(cbind(all_wts1, portfolio_values1))
## Warning in tk_tbl.data.frame(cbind(all_wts1, portfolio_values1)): Warning: No
## index to preserve. Object otherwise converted to tibble successfully.
We have the weights in each asset with the risk and returns along with the Sharpe ratio of each portfolio. We use daily data to determine the portfolios.
Next lets look at the portfolios that matter the most.
min_var1 <- portfolio_values1[which.min(portfolio_values1$Risk1),]
min_var2 <- portfolio_values1[which.min(portfolio_values1$Risk2),]
min_var3 <- portfolio_values1[which.min(portfolio_values1$Risk3),]
min_var4 <- portfolio_values1[which.min(portfolio_values1$Risk4),]
min_mad <- portfolio_values1[which.min(portfolio_values1$Risk5),]
max_sr1 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio1),]
max_sr2 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio2),]
max_sr3 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio3),]
max_sr4 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio4),]
max_sr5 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio5),]
rbind(min_var1, min_var2, min_var3, min_var4, min_mad, max_sr1, max_sr2, max_sr3, max_sr4, max_sr5)
## # A tibble: 10 × 18
## AAPL BAC CVX NVDA PEP SLB XRP.USD Return Risk1 Risk2
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.297 0.141 0.186 0.0201 0.330 0.0154 0.00934 0.00106 0.00889 0.00331
## 2 0.312 0.267 0.0473 0.0391 0.304 0.0138 0.0170 0.00129 0.00919 0.00315
## 3 0.297 0.141 0.186 0.0201 0.330 0.0154 0.00934 0.00106 0.00889 0.00331
## 4 0.368 0.102 0.0498 0.0141 0.443 0.00352 0.0198 0.000965 0.00932 0.00317
## 5 0.297 0.141 0.186 0.0201 0.330 0.0154 0.00934 0.00106 0.00889 0.00331
## 6 0.123 0.498 0.0908 0.148 0.0624 0.00252 0.0757 0.00268 0.0141 0.00532
## 7 0.00923 0.314 0.288 0.0752 0.209 0.0434 0.0619 0.00226 0.0128 0.00403
## 8 0.00566 0.371 0.0612 0.239 0.185 0.107 0.0315 0.00221 0.0123 0.00429
## 9 0.0303 0.462 0.124 0.0698 0.127 0.132 0.0556 0.00241 0.0140 0.00438
## 10 0.0538 0.361 0.0638 0.156 0.257 0.0223 0.0850 0.00256 0.0135 0.00549
## # ℹ 8 more variables: Risk3 <dbl>, Risk4 <dbl>, Risk5 <dbl>,
## # SharpeRatio1 <dbl>, SharpeRatio2 <dbl>, SharpeRatio3 <dbl>,
## # SharpeRatio4 <dbl>, SharpeRatio5 <dbl>
xtable(rbind(min_var1, min_var2, min_var3, min_var4, min_mad, max_sr1, max_sr2, max_sr3, max_sr4, max_sr5), digits = 6)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:27:48 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrrrrrrrrrrrrr}
## \hline
## & AAPL & BAC & CVX & NVDA & PEP & SLB & XRP.USD & Return & Risk1 & Risk2 & Risk3 & Risk4 & Risk5 & SharpeRatio1 & SharpeRatio2 & SharpeRatio3 & SharpeRatio4 & SharpeRatio5 \\
## \hline
## 1 & 0.297369 & 0.141253 & 0.186225 & 0.020087 & 0.330307 & 0.015419 & 0.009340 & 0.001062 & 0.008894 & 0.003308 & 0.005727 & 0.002130 & 0.006793 & 0.119403 & 0.321043 & 0.185421 & 0.498548 & 0.156334 \\
## 2 & 0.311510 & 0.266874 & 0.047295 & 0.039072 & 0.304427 & 0.013832 & 0.016990 & 0.001291 & 0.009190 & 0.003154 & 0.005901 & 0.002025 & 0.007017 & 0.140486 & 0.409332 & 0.218787 & 0.637475 & 0.184003 \\
## 3 & 0.297369 & 0.141253 & 0.186225 & 0.020087 & 0.330307 & 0.015419 & 0.009340 & 0.001062 & 0.008894 & 0.003308 & 0.005727 & 0.002130 & 0.006793 & 0.119403 & 0.321043 & 0.185421 & 0.498548 & 0.156334 \\
## 4 & 0.368449 & 0.101786 & 0.049769 & 0.014103 & 0.442591 & 0.003522 & 0.019780 & 0.000965 & 0.009318 & 0.003165 & 0.005793 & 0.001968 & 0.007275 & 0.103528 & 0.304751 & 0.166505 & 0.490136 & 0.132603 \\
## 5 & 0.297369 & 0.141253 & 0.186225 & 0.020087 & 0.330307 & 0.015419 & 0.009340 & 0.001062 & 0.008894 & 0.003308 & 0.005727 & 0.002130 & 0.006793 & 0.119403 & 0.321043 & 0.185421 & 0.498548 & 0.156334 \\
## 6 & 0.122669 & 0.497735 & 0.090817 & 0.148087 & 0.062434 & 0.002519 & 0.075739 & 0.002685 & 0.014119 & 0.005323 & 0.009168 & 0.003457 & 0.010736 & 0.190146 & 0.504320 & 0.292832 & 0.776674 & 0.250057 \\
## 7 & 0.009227 & 0.313519 & 0.288178 & 0.075214 & 0.208527 & 0.043420 & 0.061915 & 0.002255 & 0.012753 & 0.004034 & 0.007685 & 0.002431 & 0.010145 & 0.176842 & 0.559106 & 0.293460 & 0.927806 & 0.222298 \\
## 8 & 0.005661 & 0.370568 & 0.061222 & 0.238704 & 0.185056 & 0.107295 & 0.031493 & 0.002206 & 0.012334 & 0.004293 & 0.007438 & 0.002589 & 0.009838 & 0.178886 & 0.513915 & 0.296624 & 0.852156 & 0.224260 \\
## 9 & 0.030307 & 0.461805 & 0.124221 & 0.069753 & 0.126781 & 0.131509 & 0.055626 & 0.002410 & 0.013985 & 0.004383 & 0.008248 & 0.002585 & 0.011248 & 0.172353 & 0.549918 & 0.292252 & 0.932473 & 0.214284 \\
## 10 & 0.053823 & 0.361326 & 0.063795 & 0.156457 & 0.257232 & 0.022330 & 0.085039 & 0.002562 & 0.013535 & 0.005490 & 0.008968 & 0.003637 & 0.010127 & 0.189253 & 0.466613 & 0.285639 & 0.704258 & 0.252958 \\
## \hline
## \end{tabular}
## \end{table}
# change min_var1[1:nassets] and all the indexes after that accordingly
p1 <- cbind(min_var1[1:nasset], 252*min_var1[nasset+1], sqrt(252)*min_var1[nasset+2], sqrt(252)*min_var1[nasset+7])
p2 <- cbind(min_var2[1:nasset], 252*min_var2[nasset+1], sqrt(252)*min_var2[nasset+3], sqrt(252)*min_var2[nasset+8])
p3 <- cbind(min_var3[1:nasset], 252*min_var3[nasset+1], sqrt(252)*min_var3[nasset+4], sqrt(252)*min_var3[nasset+9])
p4 <- cbind(min_var4[1:nasset], 252*min_var4[nasset+1], sqrt(252)*min_var4[nasset+5], sqrt(252)*min_var4[nasset+10])
p5 <- cbind(min_mad[1:nasset], 252*min_mad[nasset+1], sqrt(252)*min_mad[nasset+6], sqrt(252)*min_mad[nasset+11])
xtable(t(rbind(as.numeric(p1), as.numeric(p2), as.numeric(p3), as.numeric(p4), as.numeric(p5))), digits = 5)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:27:48 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.29737 & 0.31151 & 0.29737 & 0.36845 & 0.29737 \\
## 2 & 0.14125 & 0.26687 & 0.14125 & 0.10179 & 0.14125 \\
## 3 & 0.18623 & 0.04729 & 0.18623 & 0.04977 & 0.18623 \\
## 4 & 0.02009 & 0.03907 & 0.02009 & 0.01410 & 0.02009 \\
## 5 & 0.33031 & 0.30443 & 0.33031 & 0.44259 & 0.33031 \\
## 6 & 0.01542 & 0.01383 & 0.01542 & 0.00352 & 0.01542 \\
## 7 & 0.00934 & 0.01699 & 0.00934 & 0.01978 & 0.00934 \\
## 8 & 0.26762 & 0.32535 & 0.26762 & 0.24309 & 0.26762 \\
## 9 & 0.14119 & 0.05007 & 0.09092 & 0.03124 & 0.10784 \\
## 10 & 1.89546 & 6.49795 & 2.94346 & 7.78067 & 2.48173 \\
## \hline
## \end{tabular}
## \end{table}
# change max_sr[1:nassets] and all the indexes after that accordingly
p1 <- cbind(max_sr1[1:nasset], 252*max_sr1[nasset+1], sqrt(252)*max_sr1[nasset+2], sqrt(252)*max_sr1[nasset+7])
p2 <- cbind(max_sr2[1:nasset], 252*max_sr2[nasset+1], sqrt(252)*max_sr2[nasset+3], sqrt(252)*max_sr2[nasset+8])
p3 <- cbind(max_sr3[1:nasset], 252*max_sr3[nasset+1], sqrt(252)*max_sr3[nasset+4], sqrt(252)*max_sr3[nasset+9])
p4 <- cbind(max_sr4[1:nasset], 252*max_sr4[nasset+1], sqrt(252)*max_sr4[nasset+5], sqrt(252)*max_sr4[nasset+10])
p5 <- cbind(max_sr5[1:nasset], 252*max_sr5[nasset+1], sqrt(252)*max_sr5[nasset+6], sqrt(252)*max_sr5[nasset+11])
xtable(t(rbind(as.numeric(p1), as.numeric(p2), as.numeric(p3), as.numeric(p4), as.numeric(p5))), digits = 5)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:27:48 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.12267 & 0.00923 & 0.00566 & 0.03031 & 0.05382 \\
## 2 & 0.49774 & 0.31352 & 0.37057 & 0.46180 & 0.36133 \\
## 3 & 0.09082 & 0.28818 & 0.06122 & 0.12422 & 0.06379 \\
## 4 & 0.14809 & 0.07521 & 0.23870 & 0.06975 & 0.15646 \\
## 5 & 0.06243 & 0.20853 & 0.18506 & 0.12678 & 0.25723 \\
## 6 & 0.00252 & 0.04342 & 0.10730 & 0.13151 & 0.02233 \\
## 7 & 0.07574 & 0.06192 & 0.03149 & 0.05563 & 0.08504 \\
## 8 & 0.67653 & 0.56831 & 0.55600 & 0.60741 & 0.64552 \\
## 9 & 0.22413 & 0.06403 & 0.11808 & 0.04103 & 0.16075 \\
## 10 & 3.01847 & 8.87553 & 4.70875 & 14.80254 & 4.01559 \\
## \hline
## \end{tabular}
## \end{table}
nasset <- ncol(asset_returns)
w1 <- min_var1[, 1:nasset] %>% gather () %>% arrange(desc(value))
w2 <- min_var2[, 1:nasset] %>% gather () %>% arrange(desc(value))
w3 <- min_var3[, 1:nasset] %>% gather () %>% arrange(desc(value))
w4 <- min_var4[, 1:nasset] %>% gather () %>% arrange(desc(value))
w5 <- min_mad[, 1:nasset] %>% gather () %>% arrange(desc(value))
w6 <- max_sr1[, 1:nasset] %>% gather () %>% arrange(desc(value))
w7 <- max_sr2[, 1:nasset] %>% gather () %>% arrange(desc(value))
w8 <- max_sr3[, 1:nasset] %>% gather () %>% arrange(desc(value))
w9 <- max_sr4[, 1:nasset] %>% gather () %>% arrange(desc(value))
w10 <- max_sr5[, 1:nasset] %>% gather () %>% arrange(desc(value))
xtable(cbind(head (w1, 10), head (w2, 10), head (w3, 10), head (w4, 10), head (w5, 10), head (w6, 10), head (w7, 10), head (w8, 10), head (w9, 10), head (w10, 10)), digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:27:48 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rlrlrlrlrlrlrlrlrlrlr}
## \hline
## & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value \\
## \hline
## 1 & PEP & 0.3303 & AAPL & 0.3115 & PEP & 0.3303 & PEP & 0.4426 & PEP & 0.3303 & BAC & 0.4977 & BAC & 0.3135 & BAC & 0.3706 & BAC & 0.4618 & BAC & 0.3613 \\
## 2 & AAPL & 0.2974 & PEP & 0.3044 & AAPL & 0.2974 & AAPL & 0.3684 & AAPL & 0.2974 & NVDA & 0.1481 & CVX & 0.2882 & NVDA & 0.2387 & SLB & 0.1315 & PEP & 0.2572 \\
## 3 & CVX & 0.1862 & BAC & 0.2669 & CVX & 0.1862 & BAC & 0.1018 & CVX & 0.1862 & AAPL & 0.1227 & PEP & 0.2085 & PEP & 0.1851 & PEP & 0.1268 & NVDA & 0.1565 \\
## 4 & BAC & 0.1413 & CVX & 0.0473 & BAC & 0.1413 & CVX & 0.0498 & BAC & 0.1413 & CVX & 0.0908 & NVDA & 0.0752 & SLB & 0.1073 & CVX & 0.1242 & XRP.USD & 0.0850 \\
## 5 & NVDA & 0.0201 & NVDA & 0.0391 & NVDA & 0.0201 & XRP.USD & 0.0198 & NVDA & 0.0201 & XRP.USD & 0.0757 & XRP.USD & 0.0619 & CVX & 0.0612 & NVDA & 0.0698 & CVX & 0.0638 \\
## 6 & SLB & 0.0154 & XRP.USD & 0.0170 & SLB & 0.0154 & NVDA & 0.0141 & SLB & 0.0154 & PEP & 0.0624 & SLB & 0.0434 & XRP.USD & 0.0315 & XRP.USD & 0.0556 & AAPL & 0.0538 \\
## 7 & XRP.USD & 0.0093 & SLB & 0.0138 & XRP.USD & 0.0093 & SLB & 0.0035 & XRP.USD & 0.0093 & SLB & 0.0025 & AAPL & 0.0092 & AAPL & 0.0057 & AAPL & 0.0303 & SLB & 0.0223 \\
## \hline
## \end{tabular}
## \end{table}
Lets plot the weights of each portfolio. First with the minimum variance portfolio.
p1 <- min_var4 %>%
gather(colnames(asset_returns)[1]:colnames(asset_returns)[nasset], key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset,Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Assets', y = 'Weights', title = "Minimum Risk Portfolio Weights") +
scale_y_continuous(labels = scales::percent)
ggplotly(p1)
p2 <- max_sr4 %>%
gather(colnames(asset_returns)[1]:colnames(asset_returns)[nasset], key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset, Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Assets', y = 'Weights', title = "Tangency Portfolio Weights") +
scale_y_continuous(labels = scales::percent)
ggplotly(p2)
#convert daily return, risk, SR to annualized ones
portfolio_values1_annual <- portfolio_values1 %>% mutate(Return = Return * 252) %>% mutate(Risk1 = Risk1 * sqrt(252), Risk2 = Risk2 * sqrt(252), Risk3 = Risk3 * sqrt(252), Risk4 = Risk4 * sqrt(252), Risk5 = Risk5 * sqrt(252)) %>% mutate(SharpeRatio1 = SharpeRatio1 * sqrt(252), SharpeRatio2 = SharpeRatio2 * sqrt(252), SharpeRatio3 = SharpeRatio3 * sqrt(252), SharpeRatio4 = SharpeRatio4 * sqrt(252), SharpeRatio5 = SharpeRatio5 * sqrt(252))
min_var1.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk1),]
min_var2.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk2),]
min_var3.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk3),]
min_var4.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk4),]
min_mad.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk5),]
max_sr1.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio1),]
max_sr2.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio2),]
max_sr3.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio3),]
max_sr4.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio4),]
max_sr5.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio5),]
rbind(min_var1.a, min_var2.a, min_var3.a, min_var4.a, min_mad.a, max_sr1.a, max_sr2.a, max_sr3.a, max_sr4.a, max_sr5.a)
## # A tibble: 10 × 18
## AAPL BAC CVX NVDA PEP SLB XRP.USD Return Risk1 Risk2 Risk3
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.297 0.141 0.186 0.0201 0.330 0.0154 0.00934 0.268 0.141 0.0525 0.0909
## 2 0.312 0.267 0.0473 0.0391 0.304 0.0138 0.0170 0.325 0.146 0.0501 0.0937
## 3 0.297 0.141 0.186 0.0201 0.330 0.0154 0.00934 0.268 0.141 0.0525 0.0909
## 4 0.368 0.102 0.0498 0.0141 0.443 0.00352 0.0198 0.243 0.148 0.0502 0.0920
## 5 0.297 0.141 0.186 0.0201 0.330 0.0154 0.00934 0.268 0.141 0.0525 0.0909
## 6 0.123 0.498 0.0908 0.148 0.0624 0.00252 0.0757 0.677 0.224 0.0845 0.146
## 7 0.00923 0.314 0.288 0.0752 0.209 0.0434 0.0619 0.568 0.202 0.0640 0.122
## 8 0.00566 0.371 0.0612 0.239 0.185 0.107 0.0315 0.556 0.196 0.0682 0.118
## 9 0.0303 0.462 0.124 0.0698 0.127 0.132 0.0556 0.607 0.222 0.0696 0.131
## 10 0.0538 0.361 0.0638 0.156 0.257 0.0223 0.0850 0.646 0.215 0.0871 0.142
## # ℹ 7 more variables: Risk4 <dbl>, Risk5 <dbl>, SharpeRatio1 <dbl>,
## # SharpeRatio2 <dbl>, SharpeRatio3 <dbl>, SharpeRatio4 <dbl>,
## # SharpeRatio5 <dbl>
p1 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk1, y = Return, color = SharpeRatio1)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (SD)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk1,
y = Return), data = min_var1.a, color = 'orange') +
geom_point(aes(x = Risk1,
y = Return), data = max_sr1.a, color = 'orange4', shape = 18)
ggplotly(p1)
p2 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk2, y = Return, color = SharpeRatio2)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VEV)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk2,
y = Return), data = min_var2.a, color = 'green') +
geom_point(aes(x = Risk2,
y = Return), data = max_sr2.a, color = 'green4', shape = 18)
ggplotly(p2)
p3 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk3, y = Return, color = SharpeRatio3)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VES)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk3,
y = Return), data = min_var3.a, color = 'red') +
geom_point(aes(x = Risk3,
y = Return), data = max_sr3.a, color = 'red4', shape = 18)
ggplotly(p3)
p4 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk4, y = Return, color = SharpeRatio4)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VESV)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk4,
y = Return), data = min_var4.a, color = 'purple') +
geom_point(aes(x = Risk4,
y = Return), data = max_sr4.a, color = 'purple4', shape = 18)
ggplotly(p4)
p5 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk5, y = Return, color = SharpeRatio5)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (MAD)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk5,
y = Return), data = min_mad.a, color = 'blue') +
geom_point(aes(x = Risk5,
y = Return), data = max_sr5.a, color = 'blue4', shape = 18)
ggplotly(p5)
MVP1 <- as.matrix(test)%*%as.vector(as.numeric(min_var1[1:nasset]))
MVP2 <- as.matrix(test)%*%as.vector(as.numeric(min_var2[1:nasset]))
MVP3 <- as.matrix(test)%*%as.vector(as.numeric(min_var3[1:nasset]))
MVP4 <- as.matrix(test)%*%as.vector(as.numeric(min_var4[1:nasset]))
MVP5 <- as.matrix(test)%*%as.vector(as.numeric(min_mad[1:nasset]))
TP1<-as.matrix(test)%*%as.vector(as.numeric(max_sr1[1:nasset]))
TP2<-as.matrix(test)%*%as.vector(as.numeric(max_sr2[1:nasset]))
TP3<-as.matrix(test)%*%as.vector(as.numeric(max_sr3[1:nasset]))
TP4<-as.matrix(test)%*%as.vector(as.numeric(max_sr4[1:nasset]))
TP5<-as.matrix(test)%*%as.vector(as.numeric(max_sr5[1:nasset]))
EWQ<-as.matrix(test)%*%as.vector(rep(1/nasset, nasset))
assets <- c("MVP1", "MVP2", "MVP3", "MVP4", "MVP5", "TP1", "TP2", "TP3", "TP4", "TP5", "EWQ")
#Portfolios <- merge(test[, 1], cumsum(MVP1), cumsum(MVP2), cumsum(MVP3), cumsum(MVP4), cumsum(MVP5), cumsum(TP1), cumsum(TP2), cumsum(TP3), cumsum(TP4), cumsum(TP5), cumsum(EWQ))[, -c(1)]
Portfolios <- cbind.data.frame(cumsum(MVP1), cumsum(MVP2), cumsum(MVP3), cumsum(MVP4), cumsum(MVP5), cumsum(TP1), cumsum(TP2), cumsum(TP3), cumsum(TP4), cumsum(TP5), cumsum(EWQ))
colnames(Portfolios) <- assets
# Define start and end dates
start_date <- as.Date("2021-01-01")
end_date <- as.Date("2021-12-31")
# Create a sequence of dates
date_sequence <- seq(start_date, end_date, by = "day")
#date_sequence
# Number of last values to select
nTemp <- nrow(Portfolios)
# Select the last 'n' values from the vector
TestDates <- date_sequence[(length(date_sequence) - nTemp + 1):length(date_sequence)]
#TestDates
row.names(Portfolios) <- TestDates
dygraph(Portfolios, main = 'Cummulative Returns for Test Period')%>%
dySeries('MVP1', label = 'MVP', col = "orange") %>%
dySeries('MVP2', label = 'MRP2', col = "green") %>%
dySeries('MVP3', label = 'MRP3', col = "red") %>%
dySeries('MVP4', label = 'MRP4', col = "purple") %>%
dySeries('MVP5', label = 'MRP5', col = "blue") %>%
dySeries('TP1', label = 'TP', col = "orange", drawPoints = TRUE) %>%
dySeries('TP2', label = 'MRRP2', col = "green", drawPoints = TRUE) %>%
dySeries('TP3', label = 'MRRP3', col = "red", drawPoints = TRUE) %>%
dySeries('TP4', label = 'MRRP4', col = "purple", drawPoints = TRUE) %>%
dySeries('TP5', label = 'MRRP5', col = "blue", drawPoints = TRUE) %>%
dySeries('EWQ', label = 'EWQ', col = "black") %>%
dyRangeSelector(height = 30)%>%
dyLegend(width = 500)
CumReturnVolCorr_low_risk <- cumsum(TP2)
CumReturnVolCorr_low_risk
## [1] 0.002555038 0.008148119 0.015396381 0.014232691 0.011918789 0.014436869
## [7] 0.037174301 0.049289553 0.046077611 0.057035534 0.068993020 0.059486870
## [13] 0.067726495 0.071451154 0.083290276 0.062112277 0.077748989 0.082903923
## [19] 0.085788690 0.090199421 0.097651088 0.101098946 0.102278061 0.111366403
## [25] 0.110162791 0.100449995 0.104221958 0.099149888 0.106202029 0.103394252
## [31] 0.095397129 0.094887169 0.086506473 0.093153531 0.111410106 0.113667777
## [37] 0.079823833 0.091674711 0.071360655 0.061632520 0.082385415 0.071974509
## [43] 0.074075609 0.088751616 0.089175957 0.086555834 0.086327314 0.066457386
## [49] 0.071963229 0.079453741 0.083526606 0.060727949 0.062290597 0.083894701
## [55] 0.088993266 0.093699238 0.102956810 0.097832987 0.092511377 0.091063275
DD_AP_2021_highest_mean <- read.csv("~/Desktop/PO/AP/DD/2021/DD_AP_2021_highest_mean.csv")
#remove the date column
asset_prices<-DD_AP_2021_highest_mean[,-1]
# calculate returns
ret_tidy1 = apply(asset_prices,2, log)
head(ret_tidy1)
## BTC.USD ETH.USD GOOGL LTC.USD MRNA NVDA XRP.USD
## [1,] 10.37261 6.947200 4.455432 5.042181 4.716085 2.571176 -1.441059
## [2,] 10.43389 7.003071 4.463464 5.066352 4.692998 2.593143 -1.483907
## [3,] 10.51391 7.095986 4.453547 5.129999 4.755829 2.532381 -1.382721
## [4,] 10.58079 7.111250 4.482978 5.133537 4.745714 2.588601 -1.120852
## [5,] 10.61638 7.110041 4.496130 5.154908 4.725173 2.583548 -1.129391
## [6,] 10.47916 6.994066 4.472754 4.936287 4.764394 2.609184 -1.241657
ret_tidy2 = diff(ret_tidy1)
head(ret_tidy2)
## BTC.USD ETH.USD GOOGL LTC.USD MRNA
## [1,] 0.06128001 0.055870971 0.008031959 0.024171054 -0.02308738
## [2,] 0.08002183 0.092915153 -0.009916683 0.063646493 0.06283118
## [3,] 0.06687092 0.015263361 0.029431282 0.003537933 -0.01011468
## [4,] 0.03559289 -0.001209006 0.013151875 0.021371299 -0.02054142
## [5,] -0.13721491 -0.115974167 -0.023376743 -0.218621195 0.03922073
## [6,] -0.04731648 -0.043793325 -0.010796655 -0.048679021 0.06031356
## NVDA XRP.USD
## [1,] 0.021966844 -0.042848272
## [2,] -0.060762150 0.101186404
## [3,] 0.056219881 0.261869023
## [4,] -0.005052456 -0.008539383
## [5,] 0.025635094 -0.112266243
## [6,] -0.010090108 0.011077016
ret_tidy = exp (ret_tidy2) - 1 #simple returns
#remove first row
asset_returns <- ret_tidy[-1,]
#no.of assets in the portfolio
nasset<-ncol(asset_returns)
# testing and training data sets (each data set has 252 observations)
# Divide the data set in to 3:1 (75% training and 25% testing)
# testing period - January - September (189 data points)
# training period - October - December (62 data points)
n.total<-252
n.train<- 189
train = asset_returns[1:n.train,]
test = asset_returns[-(1:(n.train)),]
##summary statistics
rhosign<-apply(as.matrix(train), MARGIN=2, FUN=rho.cal)
rhovol<-apply(as.matrix(train), MARGIN=2, FUN=rho.vol)
assetsummary<-data.frame(apply(train, 2, mean), apply(train, 2, sd), rhovol, rhosign, apply(train, 2, skewness),
apply(train, 2, kurtosis))
xtable(assetsummary, digits=4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:27:56 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrr}
## \hline
## & apply.train..2..mean. & apply.train..2..sd. & rhovol & rhosign & apply.train..2..skewness. & apply.train..2..kurtosis. \\
## \hline
## BTC.USD & 0.0036 & 0.0524 & 0.9154 & 0.7639 & -0.0173 & 1.0727 \\
## ETH.USD & 0.0086 & 0.0693 & 0.9118 & 0.7547 & -0.3813 & 1.6877 \\
## GOOGL & 0.0025 & 0.0155 & 0.9080 & 0.7001 & 0.4348 & 2.8677 \\
## LTC.USD & 0.0031 & 0.0700 & 0.8801 & 0.7390 & -1.1581 & 3.5804 \\
## MRNA & 0.0070 & 0.0472 & 0.9194 & 0.7814 & 0.0317 & 0.7301 \\
## NVDA & 0.0026 & 0.0257 & 0.9333 & 0.7707 & -0.0328 & 0.4990 \\
## XRP.USD & 0.0129 & 0.0994 & 0.8812 & 0.6629 & 1.3968 & 7.5578 \\
## \hline
## \end{tabular}
## \end{table}
plot(train, legend.loc=1)
## Warning in plot.window(...): "legend.loc" is not a graphical parameter
## Warning in plot.xy(xy, type, ...): "legend.loc" is not a graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "legend.loc" is
## not a graphical parameter
## Warning in axis(side = side, at = at, labels = labels, ...): "legend.loc" is
## not a graphical parameter
## Warning in box(...): "legend.loc" is not a graphical parameter
## Warning in title(...): "legend.loc" is not a graphical parameter
Lets calculate annualized portfolio return, risk, and gamma from the simulated portfolio returns with portfolio weights. (simulated weights)
## portfolio return, sd and gamma
## w is the random weight
## data = train or test
portfolio_info = function(w, data){
port.data <- data%*%as.vector(w)
port.cdf <- ecdf(port.data)
port.return <- mean (port.data)
port.sd <- sd (port.data)
port.signrho <- cor (port.data - port.return, sign(port.data - port.return))
# port.signrho3 <- cor (sign(port.data - port.return), (port.data - port.return)^3)
# port.skewrho <- cor (port.data - port.return, (port.data - port.return)^2)
port.volcor <- cor (abs(port.data - port.return), (port.data - port.return)^2) #volatlity correlation
port.skewness <- skewness (port.data) #mu_3/sigma^3
port.kurtosis <- kurtosis (port.data) #excess kurtosis mu_4/sigma^4 - 3
return(c(port.return, port.sd, port.volcor, port.signrho, port.cdf(port.return), port.skewness, port.kurtosis))
}
# In stat matrix and weight matrix nrow = no.of assets in the portfolio (need to change), ncol is fixed to 7 , for loop i in 1:nrow
stat<-matrix(0, nrow = nasset, ncol = 7)
weight<-matrix(0, nrow = nasset, ncol = nasset)
for (i in 1:nasset){
weight[i, ] <- get_weights(nasset)
stat[i, ] <- portfolio_info (weight[i, ], as.matrix(train))
}
xtable(weight, digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:27:56 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\
## \hline
## 1 & 0.1485 & 0.0245 & 0.1638 & 0.2200 & 0.1341 & 0.3079 & 0.0012 \\
## 2 & 0.0653 & 0.1040 & 0.1823 & 0.2316 & 0.1491 & 0.0483 & 0.2195 \\
## 3 & 0.2004 & 0.0905 & 0.0371 & 0.2194 & 0.1938 & 0.2293 & 0.0294 \\
## 4 & 0.1812 & 0.0717 & 0.1566 & 0.1071 & 0.1839 & 0.0817 & 0.2178 \\
## 5 & 0.2795 & 0.1131 & 0.1536 & 0.0757 & 0.0238 & 0.0064 & 0.3479 \\
## 6 & 0.2501 & 0.0098 & 0.1148 & 0.1704 & 0.1850 & 0.1994 & 0.0707 \\
## 7 & 0.1004 & 0.1559 & 0.0896 & 0.2703 & 0.0724 & 0.2217 & 0.0898 \\
## \hline
## \end{tabular}
## \end{table}
xtable(stat, digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:27:56 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 & 6 & 7 \\
## \hline
## 1 & 0.0036 & 0.0287 & 0.9214 & 0.7821 & 0.4444 & -0.5672 & 0.9871 \\
## 2 & 0.0063 & 0.0437 & 0.8989 & 0.7373 & 0.4709 & -0.5520 & 2.5923 \\
## 3 & 0.0046 & 0.0356 & 0.9114 & 0.7759 & 0.4550 & -0.6785 & 1.2662 \\
## 4 & 0.0063 & 0.0396 & 0.9110 & 0.7491 & 0.4762 & -0.3394 & 1.7941 \\
## 5 & 0.0073 & 0.0540 & 0.9055 & 0.7388 & 0.4815 & -0.1499 & 2.2881 \\
## 6 & 0.0045 & 0.0329 & 0.9151 & 0.7654 & 0.4762 & -0.5322 & 1.0220 \\
## 7 & 0.0050 & 0.0409 & 0.8954 & 0.7651 & 0.4497 & -0.8707 & 1.9612 \\
## \hline
## \end{tabular}
## \end{table}
Check for the portfolio sd can be calcualted by both the formula and sd of the simulated portfolio.
We have everything we need to perform our optimization. All we need now is to run this code on 8000 random portfolios. For that we will use a for loop.
Before we do that, we need to create empty vectors and matrix for storing our values.
#change nasset to no of assets in portfolio
num_port <- 10000
nasset <- nasset
# Creating a matrix to store the weights
all_wts1 <- matrix(nrow = num_port,
ncol = nasset)
# Creating an empty vector to store
# 8000 Portfolio returns
port_returns <- vector('numeric', length = num_port)
# Creating an empty vector to store
# 8000 Portfolio variances
port_risk.var1 <- vector('numeric', length = num_port)
port_risk.var2 <- vector('numeric', length = num_port)
port_risk.var3 <- vector('numeric', length = num_port)
port_risk.var4 <- vector('numeric', length = num_port)
port_risk.mad <- vector('numeric', length = num_port)
Sharpe_ratio.sd1 <- vector('numeric', length = num_port)
Sharpe_ratio.sd2 <- vector('numeric', length = num_port)
Sharpe_ratio.sd3 <- vector('numeric', length = num_port)
Sharpe_ratio.sd4 <- vector('numeric', length = num_port)
Sharpe_ratio.mad <- vector('numeric', length = num_port)
Next lets run the for loop 10000 times.
port.info <- matrix(0, nrow = 10000, ncol = 7)
ptm <- proc.time()
for (i in seq_along(port_returns)) {
wts <- get_weights(nasset)
# Storing weight in the matrix
all_wts1[i,] <- wts
# Portfolio returns
port.info [i, ]<- portfolio_info (wts, as.matrix(train))
# Storing Portfolio Returns values
port_returns[i] <- port.info[i, 1]
# Creating and storing portfolio risk
port_risk.var1 [i] <- port.info[i, 2]
port_risk.var2 [i] <- sqrt(1 - port.info[i, 3]^2)*port.info[i, 2]
port_risk.var3 [i] <- sqrt(1 - port.info[i, 4]^2)*port.info[i, 2]
port_risk.var4 [i] <- sqrt(1 - port.info[i, 3]^2)*sqrt(1 - port.info[i, 4]^2)*port.info[i, 2]
port_risk.mad [i] <- 2*port.info[i, 2]*port.info[i, 4]*sqrt(port.info[i, 5]*(1-port.info[i, 5]))
# Creating and storing Portfolio Sharpe Ratios
# Assuming 0% Risk free rate
Sharpe_ratio.sd1 [i] <- port_returns[i]/port_risk.var1 [i]
Sharpe_ratio.sd2 [i] <- port_returns[i]/port_risk.var2 [i]
Sharpe_ratio.sd3 [i] <- port_returns[i]/port_risk.var3 [i]
Sharpe_ratio.sd4 [i] <- port_returns[i]/port_risk.var4 [i]
Sharpe_ratio.mad [i] <- port_returns[i]/port_risk.mad [i]
}
proc.time()-ptm
## user system elapsed
## 11.440 0.225 14.890
port.info.data <- as.data.frame(port.info)
ggplot(port.info.data, aes(x=V6, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Skewness") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V7, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Kurtosis") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V6)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Skewness")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V7)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Kurtosis")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Volatility")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V2, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V3, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Volatlity Correlation") + ylab ("Volatlity")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V2)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Volatility")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V6)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Skewness")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V7)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Kurtosis")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
ggplot(port.info.data, aes(x=V4, y=V1)) + geom_point(color="blue", alpha=0.5) +geom_smooth(color="darkred") + xlab ("Sign Correlation") + ylab ("Return")
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
We now create a data table to store all the values together (using sd).
# Storing the values in the table (5 columns and 8000 rows)
portfolio_values1 <- tibble(Return = port_returns,
Risk1 = port_risk.var1,
Risk2 = port_risk.var2,
Risk3 = port_risk.var3,
Risk4 = port_risk.var4,
Risk5 = port_risk.mad,
SharpeRatio1 = Sharpe_ratio.sd1,
SharpeRatio2 = Sharpe_ratio.sd2,
SharpeRatio3 = Sharpe_ratio.sd3,
SharpeRatio4 = Sharpe_ratio.sd4,
SharpeRatio5 = Sharpe_ratio.mad,
)
# Converting matrix to a tibble and changing column names
all_wts1 <- tk_tbl(all_wts1)
## Warning in tk_tbl.data.frame(as.data.frame(data), preserve_index, rename_index,
## : Warning: No index to preserve. Object otherwise converted to tibble
## successfully.
colnames(all_wts1) <- colnames(asset_returns)
# Combing all the values together
portfolio_values1 <- tk_tbl(cbind(all_wts1, portfolio_values1))
## Warning in tk_tbl.data.frame(cbind(all_wts1, portfolio_values1)): Warning: No
## index to preserve. Object otherwise converted to tibble successfully.
We have the weights in each asset with the risk and returns along with the Sharpe ratio of each portfolio. We use daily data to determine the portfolios.
Next lets look at the portfolios that matter the most.
min_var1 <- portfolio_values1[which.min(portfolio_values1$Risk1),]
min_var2 <- portfolio_values1[which.min(portfolio_values1$Risk2),]
min_var3 <- portfolio_values1[which.min(portfolio_values1$Risk3),]
min_var4 <- portfolio_values1[which.min(portfolio_values1$Risk4),]
min_mad <- portfolio_values1[which.min(portfolio_values1$Risk5),]
max_sr1 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio1),]
max_sr2 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio2),]
max_sr3 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio3),]
max_sr4 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio4),]
max_sr5 <- portfolio_values1[which.max(portfolio_values1$SharpeRatio5),]
rbind(min_var1, min_var2, min_var3, min_var4, min_mad, max_sr1, max_sr2, max_sr3, max_sr4, max_sr5)
## # A tibble: 10 × 18
## BTC.USD ETH.USD GOOGL LTC.USD MRNA NVDA XRP.USD Return Risk1 Risk2
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.00278 0.0576 0.409 0.0556 0.239 0.236 0.000836 0.00398 0.0199 0.00621
## 2 0.0627 0.000187 0.349 0.0232 0.165 0.355 0.0457 0.00382 0.0200 0.00583
## 3 0.00278 0.0576 0.409 0.0556 0.239 0.236 0.000836 0.00398 0.0199 0.00621
## 4 0.0627 0.000187 0.349 0.0232 0.165 0.355 0.0457 0.00382 0.0200 0.00583
## 5 0.0627 0.000187 0.349 0.0232 0.165 0.355 0.0457 0.00382 0.0200 0.00583
## 6 0.0156 0.0685 0.357 0.0149 0.365 0.107 0.0719 0.00534 0.0242 0.00812
## 7 0.0192 0.123 0.295 0.00720 0.167 0.333 0.0551 0.00462 0.0224 0.00679
## 8 0.0156 0.0685 0.357 0.0149 0.365 0.107 0.0719 0.00534 0.0242 0.00812
## 9 0.0192 0.123 0.295 0.00720 0.167 0.333 0.0551 0.00462 0.0224 0.00679
## 10 0.0156 0.0685 0.357 0.0149 0.365 0.107 0.0719 0.00534 0.0242 0.00812
## # ℹ 8 more variables: Risk3 <dbl>, Risk4 <dbl>, Risk5 <dbl>,
## # SharpeRatio1 <dbl>, SharpeRatio2 <dbl>, SharpeRatio3 <dbl>,
## # SharpeRatio4 <dbl>, SharpeRatio5 <dbl>
xtable(rbind(min_var1, min_var2, min_var3, min_var4, min_mad, max_sr1, max_sr2, max_sr3, max_sr4, max_sr5), digits = 6)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:28:26 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrrrrrrrrrrrrrrr}
## \hline
## & BTC.USD & ETH.USD & GOOGL & LTC.USD & MRNA & NVDA & XRP.USD & Return & Risk1 & Risk2 & Risk3 & Risk4 & Risk5 & SharpeRatio1 & SharpeRatio2 & SharpeRatio3 & SharpeRatio4 & SharpeRatio5 \\
## \hline
## 1 & 0.002779 & 0.057616 & 0.408870 & 0.055550 & 0.238675 & 0.235673 & 0.000836 & 0.003983 & 0.019943 & 0.006213 & 0.012412 & 0.003867 & 0.015605 & 0.199711 & 0.641025 & 0.320903 & 1.030021 & 0.255231 \\
## 2 & 0.062723 & 0.000187 & 0.348517 & 0.023245 & 0.164610 & 0.354994 & 0.045725 & 0.003820 & 0.019961 & 0.005825 & 0.012491 & 0.003645 & 0.015563 & 0.191397 & 0.655836 & 0.305841 & 1.047985 & 0.245473 \\
## 3 & 0.002779 & 0.057616 & 0.408870 & 0.055550 & 0.238675 & 0.235673 & 0.000836 & 0.003983 & 0.019943 & 0.006213 & 0.012412 & 0.003867 & 0.015605 & 0.199711 & 0.641025 & 0.320903 & 1.030021 & 0.255231 \\
## 4 & 0.062723 & 0.000187 & 0.348517 & 0.023245 & 0.164610 & 0.354994 & 0.045725 & 0.003820 & 0.019961 & 0.005825 & 0.012491 & 0.003645 & 0.015563 & 0.191397 & 0.655836 & 0.305841 & 1.047985 & 0.245473 \\
## 5 & 0.062723 & 0.000187 & 0.348517 & 0.023245 & 0.164610 & 0.354994 & 0.045725 & 0.003820 & 0.019961 & 0.005825 & 0.012491 & 0.003645 & 0.015563 & 0.191397 & 0.655836 & 0.305841 & 1.047985 & 0.245473 \\
## 6 & 0.015555 & 0.068464 & 0.356636 & 0.014900 & 0.365307 & 0.107210 & 0.071928 & 0.005341 & 0.024168 & 0.008123 & 0.014545 & 0.004889 & 0.019287 & 0.221010 & 0.657590 & 0.367218 & 1.092619 & 0.276932 \\
## 7 & 0.019187 & 0.122989 & 0.295049 & 0.007203 & 0.167288 & 0.333179 & 0.055104 & 0.004623 & 0.022380 & 0.006789 & 0.013510 & 0.004099 & 0.017786 & 0.206571 & 0.680917 & 0.342185 & 1.127939 & 0.259932 \\
## 8 & 0.015555 & 0.068464 & 0.356636 & 0.014900 & 0.365307 & 0.107210 & 0.071928 & 0.005341 & 0.024168 & 0.008123 & 0.014545 & 0.004889 & 0.019287 & 0.221010 & 0.657590 & 0.367218 & 1.092619 & 0.276932 \\
## 9 & 0.019187 & 0.122989 & 0.295049 & 0.007203 & 0.167288 & 0.333179 & 0.055104 & 0.004623 & 0.022380 & 0.006789 & 0.013510 & 0.004099 & 0.017786 & 0.206571 & 0.680917 & 0.342185 & 1.127939 & 0.259932 \\
## 10 & 0.015555 & 0.068464 & 0.356636 & 0.014900 & 0.365307 & 0.107210 & 0.071928 & 0.005341 & 0.024168 & 0.008123 & 0.014545 & 0.004889 & 0.019287 & 0.221010 & 0.657590 & 0.367218 & 1.092619 & 0.276932 \\
## \hline
## \end{tabular}
## \end{table}
# change min_var1[1:nassets] and all the indexes after that accordingly
p1 <- cbind(min_var1[1:nasset], 252*min_var1[nasset+1], sqrt(252)*min_var1[nasset+2], sqrt(252)*min_var1[nasset+7])
p2 <- cbind(min_var2[1:nasset], 252*min_var2[nasset+1], sqrt(252)*min_var2[nasset+3], sqrt(252)*min_var2[nasset+8])
p3 <- cbind(min_var3[1:nasset], 252*min_var3[nasset+1], sqrt(252)*min_var3[nasset+4], sqrt(252)*min_var3[nasset+9])
p4 <- cbind(min_var4[1:nasset], 252*min_var4[nasset+1], sqrt(252)*min_var4[nasset+5], sqrt(252)*min_var4[nasset+10])
p5 <- cbind(min_mad[1:nasset], 252*min_mad[nasset+1], sqrt(252)*min_mad[nasset+6], sqrt(252)*min_mad[nasset+11])
xtable(t(rbind(as.numeric(p1), as.numeric(p2), as.numeric(p3), as.numeric(p4), as.numeric(p5))), digits = 5)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:28:26 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.00278 & 0.06272 & 0.00278 & 0.06272 & 0.06272 \\
## 2 & 0.05762 & 0.00019 & 0.05762 & 0.00019 & 0.00019 \\
## 3 & 0.40887 & 0.34852 & 0.40887 & 0.34852 & 0.34852 \\
## 4 & 0.05555 & 0.02325 & 0.05555 & 0.02325 & 0.02325 \\
## 5 & 0.23868 & 0.16461 & 0.23868 & 0.16461 & 0.16461 \\
## 6 & 0.23567 & 0.35499 & 0.23567 & 0.35499 & 0.35499 \\
## 7 & 0.00084 & 0.04572 & 0.00084 & 0.04572 & 0.04572 \\
## 8 & 1.00370 & 0.96274 & 1.00370 & 0.96274 & 0.96274 \\
## 9 & 0.31659 & 0.09247 & 0.19703 & 0.05787 & 0.24706 \\
## 10 & 3.17032 & 10.41107 & 5.09418 & 16.63625 & 3.89677 \\
## \hline
## \end{tabular}
## \end{table}
# change max_sr[1:nassets] and all the indexes after that accordingly
p1 <- cbind(max_sr1[1:nasset], 252*max_sr1[nasset+1], sqrt(252)*max_sr1[nasset+2], sqrt(252)*max_sr1[nasset+7])
p2 <- cbind(max_sr2[1:nasset], 252*max_sr2[nasset+1], sqrt(252)*max_sr2[nasset+3], sqrt(252)*max_sr2[nasset+8])
p3 <- cbind(max_sr3[1:nasset], 252*max_sr3[nasset+1], sqrt(252)*max_sr3[nasset+4], sqrt(252)*max_sr3[nasset+9])
p4 <- cbind(max_sr4[1:nasset], 252*max_sr4[nasset+1], sqrt(252)*max_sr4[nasset+5], sqrt(252)*max_sr4[nasset+10])
p5 <- cbind(max_sr5[1:nasset], 252*max_sr5[nasset+1], sqrt(252)*max_sr5[nasset+6], sqrt(252)*max_sr5[nasset+11])
xtable(t(rbind(as.numeric(p1), as.numeric(p2), as.numeric(p3), as.numeric(p4), as.numeric(p5))), digits = 5)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:28:26 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rrrrrr}
## \hline
## & 1 & 2 & 3 & 4 & 5 \\
## \hline
## 1 & 0.01556 & 0.01919 & 0.01556 & 0.01919 & 0.01556 \\
## 2 & 0.06846 & 0.12299 & 0.06846 & 0.12299 & 0.06846 \\
## 3 & 0.35664 & 0.29505 & 0.35664 & 0.29505 & 0.35664 \\
## 4 & 0.01490 & 0.00720 & 0.01490 & 0.00720 & 0.01490 \\
## 5 & 0.36531 & 0.16729 & 0.36531 & 0.16729 & 0.36531 \\
## 6 & 0.10721 & 0.33318 & 0.10721 & 0.33318 & 0.10721 \\
## 7 & 0.07193 & 0.05510 & 0.07193 & 0.05510 & 0.07193 \\
## 8 & 1.34600 & 1.16502 & 1.34600 & 1.16502 & 1.34600 \\
## 9 & 0.38365 & 0.10778 & 0.23090 & 0.06506 & 0.30618 \\
## 10 & 3.50842 & 10.80922 & 5.82941 & 17.90547 & 4.39617 \\
## \hline
## \end{tabular}
## \end{table}
nasset <- ncol(asset_returns)
w1 <- min_var1[, 1:nasset] %>% gather () %>% arrange(desc(value))
w2 <- min_var2[, 1:nasset] %>% gather () %>% arrange(desc(value))
w3 <- min_var3[, 1:nasset] %>% gather () %>% arrange(desc(value))
w4 <- min_var4[, 1:nasset] %>% gather () %>% arrange(desc(value))
w5 <- min_mad[, 1:nasset] %>% gather () %>% arrange(desc(value))
w6 <- max_sr1[, 1:nasset] %>% gather () %>% arrange(desc(value))
w7 <- max_sr2[, 1:nasset] %>% gather () %>% arrange(desc(value))
w8 <- max_sr3[, 1:nasset] %>% gather () %>% arrange(desc(value))
w9 <- max_sr4[, 1:nasset] %>% gather () %>% arrange(desc(value))
w10 <- max_sr5[, 1:nasset] %>% gather () %>% arrange(desc(value))
xtable(cbind(head (w1, 10), head (w2, 10), head (w3, 10), head (w4, 10), head (w5, 10), head (w6, 10), head (w7, 10), head (w8, 10), head (w9, 10), head (w10, 10)), digits = 4)
## % latex table generated in R 4.3.1 by xtable 1.8-4 package
## % Tue Sep 24 12:28:26 2024
## \begin{table}[ht]
## \centering
## \begin{tabular}{rlrlrlrlrlrlrlrlrlrlr}
## \hline
## & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value & key & value \\
## \hline
## 1 & GOOGL & 0.4089 & NVDA & 0.3550 & GOOGL & 0.4089 & NVDA & 0.3550 & NVDA & 0.3550 & MRNA & 0.3653 & NVDA & 0.3332 & MRNA & 0.3653 & NVDA & 0.3332 & MRNA & 0.3653 \\
## 2 & MRNA & 0.2387 & GOOGL & 0.3485 & MRNA & 0.2387 & GOOGL & 0.3485 & GOOGL & 0.3485 & GOOGL & 0.3566 & GOOGL & 0.2950 & GOOGL & 0.3566 & GOOGL & 0.2950 & GOOGL & 0.3566 \\
## 3 & NVDA & 0.2357 & MRNA & 0.1646 & NVDA & 0.2357 & MRNA & 0.1646 & MRNA & 0.1646 & NVDA & 0.1072 & MRNA & 0.1673 & NVDA & 0.1072 & MRNA & 0.1673 & NVDA & 0.1072 \\
## 4 & ETH.USD & 0.0576 & BTC.USD & 0.0627 & ETH.USD & 0.0576 & BTC.USD & 0.0627 & BTC.USD & 0.0627 & XRP.USD & 0.0719 & ETH.USD & 0.1230 & XRP.USD & 0.0719 & ETH.USD & 0.1230 & XRP.USD & 0.0719 \\
## 5 & LTC.USD & 0.0556 & XRP.USD & 0.0457 & LTC.USD & 0.0556 & XRP.USD & 0.0457 & XRP.USD & 0.0457 & ETH.USD & 0.0685 & XRP.USD & 0.0551 & ETH.USD & 0.0685 & XRP.USD & 0.0551 & ETH.USD & 0.0685 \\
## 6 & BTC.USD & 0.0028 & LTC.USD & 0.0232 & BTC.USD & 0.0028 & LTC.USD & 0.0232 & LTC.USD & 0.0232 & BTC.USD & 0.0156 & BTC.USD & 0.0192 & BTC.USD & 0.0156 & BTC.USD & 0.0192 & BTC.USD & 0.0156 \\
## 7 & XRP.USD & 0.0008 & ETH.USD & 0.0002 & XRP.USD & 0.0008 & ETH.USD & 0.0002 & ETH.USD & 0.0002 & LTC.USD & 0.0149 & LTC.USD & 0.0072 & LTC.USD & 0.0149 & LTC.USD & 0.0072 & LTC.USD & 0.0149 \\
## \hline
## \end{tabular}
## \end{table}
Lets plot the weights of each portfolio. First with the minimum variance portfolio.
p1 <- min_var4 %>%
gather(colnames(asset_returns)[1]:colnames(asset_returns)[nasset], key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset,Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Assets', y = 'Weights', title = "Minimum Risk Portfolio Weights") +
scale_y_continuous(labels = scales::percent)
ggplotly(p1)
p2 <- max_sr4 %>%
gather(colnames(asset_returns)[1]:colnames(asset_returns)[nasset], key = Asset,
value = Weights) %>%
mutate(Asset = as.factor(Asset)) %>%
ggplot(aes(x = fct_reorder(Asset, Weights), y = Weights, fill = Asset)) +
geom_bar(stat = 'identity') +
theme_minimal() +
labs(x = 'Assets', y = 'Weights', title = "Tangency Portfolio Weights") +
scale_y_continuous(labels = scales::percent)
ggplotly(p2)
#convert daily return, risk, SR to annualized ones
portfolio_values1_annual <- portfolio_values1 %>% mutate(Return = Return * 252) %>% mutate(Risk1 = Risk1 * sqrt(252), Risk2 = Risk2 * sqrt(252), Risk3 = Risk3 * sqrt(252), Risk4 = Risk4 * sqrt(252), Risk5 = Risk5 * sqrt(252)) %>% mutate(SharpeRatio1 = SharpeRatio1 * sqrt(252), SharpeRatio2 = SharpeRatio2 * sqrt(252), SharpeRatio3 = SharpeRatio3 * sqrt(252), SharpeRatio4 = SharpeRatio4 * sqrt(252), SharpeRatio5 = SharpeRatio5 * sqrt(252))
min_var1.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk1),]
min_var2.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk2),]
min_var3.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk3),]
min_var4.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk4),]
min_mad.a <- portfolio_values1_annual[which.min(portfolio_values1_annual$Risk5),]
max_sr1.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio1),]
max_sr2.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio2),]
max_sr3.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio3),]
max_sr4.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio4),]
max_sr5.a <- portfolio_values1_annual[which.max(portfolio_values1_annual$SharpeRatio5),]
rbind(min_var1.a, min_var2.a, min_var3.a, min_var4.a, min_mad.a, max_sr1.a, max_sr2.a, max_sr3.a, max_sr4.a, max_sr5.a)
## # A tibble: 10 × 18
## BTC.USD ETH.USD GOOGL LTC.USD MRNA NVDA XRP.USD Return Risk1 Risk2 Risk3
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 0.00278 0.0576 0.409 0.0556 0.239 0.236 0.000836 1.00 0.317 0.0986 0.197
## 2 0.0627 0.000187 0.349 0.0232 0.165 0.355 0.0457 0.963 0.317 0.0925 0.198
## 3 0.00278 0.0576 0.409 0.0556 0.239 0.236 0.000836 1.00 0.317 0.0986 0.197
## 4 0.0627 0.000187 0.349 0.0232 0.165 0.355 0.0457 0.963 0.317 0.0925 0.198
## 5 0.0627 0.000187 0.349 0.0232 0.165 0.355 0.0457 0.963 0.317 0.0925 0.198
## 6 0.0156 0.0685 0.357 0.0149 0.365 0.107 0.0719 1.35 0.384 0.129 0.231
## 7 0.0192 0.123 0.295 0.00720 0.167 0.333 0.0551 1.17 0.355 0.108 0.214
## 8 0.0156 0.0685 0.357 0.0149 0.365 0.107 0.0719 1.35 0.384 0.129 0.231
## 9 0.0192 0.123 0.295 0.00720 0.167 0.333 0.0551 1.17 0.355 0.108 0.214
## 10 0.0156 0.0685 0.357 0.0149 0.365 0.107 0.0719 1.35 0.384 0.129 0.231
## # ℹ 7 more variables: Risk4 <dbl>, Risk5 <dbl>, SharpeRatio1 <dbl>,
## # SharpeRatio2 <dbl>, SharpeRatio3 <dbl>, SharpeRatio4 <dbl>,
## # SharpeRatio5 <dbl>
p1 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk1, y = Return, color = SharpeRatio1)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (SD)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk1,
y = Return), data = min_var1.a, color = 'orange') +
geom_point(aes(x = Risk1,
y = Return), data = max_sr1.a, color = 'orange4', shape = 18)
ggplotly(p1)
p2 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk2, y = Return, color = SharpeRatio2)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VEV)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk2,
y = Return), data = min_var2.a, color = 'green') +
geom_point(aes(x = Risk2,
y = Return), data = max_sr2.a, color = 'green4', shape = 18)
ggplotly(p2)
p3 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk3, y = Return, color = SharpeRatio3)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VES)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk3,
y = Return), data = min_var3.a, color = 'red') +
geom_point(aes(x = Risk3,
y = Return), data = max_sr3.a, color = 'red4', shape = 18)
ggplotly(p3)
p4 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk4, y = Return, color = SharpeRatio4)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (VESV)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk4,
y = Return), data = min_var4.a, color = 'purple') +
geom_point(aes(x = Risk4,
y = Return), data = max_sr4.a, color = 'purple4', shape = 18)
ggplotly(p4)
p5 <- portfolio_values1_annual %>%
ggplot(aes(x = Risk5, y = Return, color = SharpeRatio5)) +
geom_point(alpha = 0.4)+
theme_classic() +
scale_y_continuous(labels = scales::percent) +
scale_x_continuous(labels = scales::percent) +
labs(x = 'Annualized Risk (MAD)',
y = 'Annualized Returns',
title = "Portfolio Optimization & Efficient Frontier") +
geom_point(aes(x = Risk5,
y = Return), data = min_mad.a, color = 'blue') +
geom_point(aes(x = Risk5,
y = Return), data = max_sr5.a, color = 'blue4', shape = 18)
ggplotly(p5)
MVP1 <- as.matrix(test)%*%as.vector(as.numeric(min_var1[1:nasset]))
MVP2 <- as.matrix(test)%*%as.vector(as.numeric(min_var2[1:nasset]))
MVP3 <- as.matrix(test)%*%as.vector(as.numeric(min_var3[1:nasset]))
MVP4 <- as.matrix(test)%*%as.vector(as.numeric(min_var4[1:nasset]))
MVP5 <- as.matrix(test)%*%as.vector(as.numeric(min_mad[1:nasset]))
TP1<-as.matrix(test)%*%as.vector(as.numeric(max_sr1[1:nasset]))
TP2<-as.matrix(test)%*%as.vector(as.numeric(max_sr2[1:nasset]))
TP3<-as.matrix(test)%*%as.vector(as.numeric(max_sr3[1:nasset]))
TP4<-as.matrix(test)%*%as.vector(as.numeric(max_sr4[1:nasset]))
TP5<-as.matrix(test)%*%as.vector(as.numeric(max_sr5[1:nasset]))
EWQ<-as.matrix(test)%*%as.vector(rep(1/nasset, nasset))
assets <- c("MVP1", "MVP2", "MVP3", "MVP4", "MVP5", "TP1", "TP2", "TP3", "TP4", "TP5", "EWQ")
#Portfolios <- merge(test[, 1], cumsum(MVP1), cumsum(MVP2), cumsum(MVP3), cumsum(MVP4), cumsum(MVP5), cumsum(TP1), cumsum(TP2), cumsum(TP3), cumsum(TP4), cumsum(TP5), cumsum(EWQ))[, -c(1)]
Portfolios <- cbind.data.frame(cumsum(MVP1), cumsum(MVP2), cumsum(MVP3), cumsum(MVP4), cumsum(MVP5), cumsum(TP1), cumsum(TP2), cumsum(TP3), cumsum(TP4), cumsum(TP5), cumsum(EWQ))
colnames(Portfolios) <- assets
# Define start and end dates
start_date <- as.Date("2021-01-01")
end_date <- as.Date("2021-12-31")
# Create a sequence of dates
date_sequence <- seq(start_date, end_date, by = "day")
#date_sequence
# Number of last values to select
nTemp <- nrow(Portfolios)
# Select the last 'n' values from the vector
TestDates <- date_sequence[(length(date_sequence) - nTemp + 1):length(date_sequence)]
#TestDates
row.names(Portfolios) <- TestDates
dygraph(Portfolios, main = 'Cummulative Returns for Test Period')%>%
dySeries('MVP1', label = 'MVP', col = "orange") %>%
dySeries('MVP2', label = 'MRP2', col = "green") %>%
dySeries('MVP3', label = 'MRP3', col = "red") %>%
dySeries('MVP4', label = 'MRP4', col = "purple") %>%
dySeries('MVP5', label = 'MRP5', col = "blue") %>%
dySeries('TP1', label = 'TP', col = "orange", drawPoints = TRUE) %>%
dySeries('TP2', label = 'MRRP2', col = "green", drawPoints = TRUE) %>%
dySeries('TP3', label = 'MRRP3', col = "red", drawPoints = TRUE) %>%
dySeries('TP4', label = 'MRRP4', col = "purple", drawPoints = TRUE) %>%
dySeries('TP5', label = 'MRRP5', col = "blue", drawPoints = TRUE) %>%
dySeries('EWQ', label = 'EWQ', col = "black") %>%
dyRangeSelector(height = 30)%>%
dyLegend(width = 500)
CumReturnVolCorr_high_mean <- cumsum(TP2)
CumReturnVolCorr_high_mean
## [1] -0.004151341 0.008509621 0.002283609 0.003017835 -0.003621603
## [6] 0.014718944 0.047013267 0.050045603 0.057604519 0.064428470
## [11] 0.070872628 0.076276114 0.058084257 0.084999748 0.106860539
## [16] 0.102715915 0.127914979 0.145004617 0.133166249 0.160639827
## [21] 0.168458483 0.179224580 0.148675681 0.183979927 0.174746345
## [26] 0.144110906 0.155779480 0.162143621 0.156921245 0.142292414
## [31] 0.140298820 0.164857816 0.197722900 0.184446635 0.187367358
## [36] 0.191187013 0.192617840 0.256939453 0.240629574 0.204900757
## [41] 0.207811793 0.181578702 0.150604828 0.194511418 0.197404845
## [46] 0.165078023 0.142819310 0.120159941 0.121243390 0.167510306
## [51] 0.136258656 0.127544015 0.123833933 0.146931672 0.145385380
## [56] 0.155540772 0.163896872 0.137886830 0.130358747 0.132225749
# Example data
CumReturnVolCorr <- data.frame(
Date = as.character(TestDates),
low_avg_risk = CumReturnVolCorr_low_avg_risk,
low_risk = CumReturnVolCorr_low_risk,
high_mean = CumReturnVolCorr_high_mean
)
library(ggplot2)
# Create the plot with date interval
ggplot(data = CumReturnVolCorr, aes(x = as.Date(Date))) +
geom_line(aes(y = low_avg_risk, color = "low_avg_risk"), lwd = 1.5) +
geom_line(aes(y = low_risk, color = "low_risk"), lwd = 1.5) +
geom_line(aes(y = high_mean, color = "high_mean"), lwd = 1.5) +
labs(y = "Cumulative Return",
x = "Date") +
scale_color_manual(name = "Data",
values = c("low_avg_risk" = "blue",
"low_risk" = "red",
"high_mean" = "green"), # Add color for the new series
labels = c("low_avg_risk" = "lowest average risk",
"low_risk" = "lowest risk",
"high_mean" = "highest mean")) + # Adjust labels
scale_x_date(date_breaks = "1 month", date_labels = "%Y-%m") + # Show dates at monthly intervals
theme_minimal()